Skip to content

Commit 40b40b3

Browse files
authored
Enable custom CPS projects to be restored (#3644)
* Rename NetCore -> CPS This better describes what these types do. * Include C++ in CPS-based project check The CPS capability indicates that the outer hierarchy of a project is owned by CPS, not that the project uses CPS. C++ will be using CPS-based components to light up PackageReference support and hence should pass this check. * Unify PackageReferences checks We were opt'ing CPS projects out of CpsProjectReferenceProjectProvider based on whether that had TargetFramework or TargetFrameworks properties, both are which are .NET-SDK specific. C++/MSIX deployment and other custom projects don't have these properties. * IsCPSCapabilityComplaint -> IsCPSCapabilityCompliant * fix formatting
1 parent f88ad39 commit 40b40b3

File tree

13 files changed

+58
-62
lines changed

13 files changed

+58
-62
lines changed

src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/GlobalSuppressions.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@
7474
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'Task<IPackageSearchMetadata> MultiSourcePackageMetadataProvider.GetLocalPackageMetadataAsync(PackageIdentity identity, bool includePrerelease, CancellationToken cancellationToken)', validate parameter 'identity' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.MultiSourcePackageMetadataProvider.GetLocalPackageMetadataAsync(NuGet.Packaging.Core.PackageIdentity,System.Boolean,System.Threading.CancellationToken)~System.Threading.Tasks.Task{NuGet.Protocol.Core.Types.IPackageSearchMetadata}")]
7575
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'Task<IPackageSearchMetadata> MultiSourcePackageMetadataProvider.GetPackageMetadataAsync(PackageIdentity identity, bool includePrerelease, CancellationToken cancellationToken)', validate parameter 'identity' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.MultiSourcePackageMetadataProvider.GetPackageMetadataAsync(NuGet.Packaging.Core.PackageIdentity,System.Boolean,System.Threading.CancellationToken)~System.Threading.Tasks.Task{NuGet.Protocol.Core.Types.IPackageSearchMetadata}")]
7676
[assembly: SuppressMessage("Build", "CA1801:Parameter identity of method MergeDeprecationMetadataAsync is never used. Remove the parameter or use it in the method body.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.MultiSourcePackageMetadataProvider.MergeDeprecationMetadataAsync(NuGet.Packaging.Core.PackageIdentity,System.Collections.Generic.IEnumerable{NuGet.Protocol.Core.Types.IPackageSearchMetadata})~System.Threading.Tasks.Task{NuGet.Protocol.PackageDeprecationMetadata}")]
77-
[assembly: SuppressMessage("Build", "CA1305:The behavior of 'string.Format(string, object)' could vary based on the current user's locale settings. Replace this call in 'NetCorePackageReferenceProject.GetAssetsFilePathAsync(bool)' with a call to 'string.Format(IFormatProvider, string, params object[])'.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.NetCorePackageReferenceProject.GetAssetsFilePathAsync(System.Boolean)~System.Threading.Tasks.Task{System.String}")]
78-
[assembly: SuppressMessage("Build", "CA1305:The behavior of 'string.Format(string, object)' could vary based on the current user's locale settings. Replace this call in 'NetCorePackageReferenceProject.GetCacheFilePathAsync()' with a call to 'string.Format(IFormatProvider, string, params object[])'.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.NetCorePackageReferenceProject.GetCacheFilePathAsync~System.Threading.Tasks.Task{System.String}")]
79-
[assembly: SuppressMessage("Build", "CA1825:Avoid unnecessary zero-length array allocations. Use Array.Empty<PackageReference>() instead.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.NetCorePackageReferenceProject.GetInstalledPackagesAsync(System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.Collections.Generic.IEnumerable{NuGet.Packaging.PackageReference}}")]
80-
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'Task<bool> NetCorePackageReferenceProject.InstallPackageAsync(string packageId, VersionRange range, INuGetProjectContext nuGetProjectContext, BuildIntegratedInstallationContext installationContext, CancellationToken token)', validate parameter 'range' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.NetCorePackageReferenceProject.InstallPackageAsync(System.String,NuGet.Versioning.VersionRange,NuGet.ProjectManagement.INuGetProjectContext,NuGet.ProjectManagement.BuildIntegratedInstallationContext,System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.Boolean}")]
81-
[assembly: SuppressMessage("Build", "CA1305:The behavior of 'string.Format(string, object)' could vary based on the current user's locale settings. Replace this call in 'NetCorePackageReferenceProject.InstallPackageAsync(string, VersionRange, INuGetProjectContext, BuildIntegratedInstallationContext, CancellationToken)' with a call to 'string.Format(IFormatProvider, string, params object[])'.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.NetCorePackageReferenceProject.InstallPackageAsync(System.String,NuGet.Versioning.VersionRange,NuGet.ProjectManagement.INuGetProjectContext,NuGet.ProjectManagement.BuildIntegratedInstallationContext,System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.Boolean}")]
82-
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'Task<bool> NetCorePackageReferenceProject.UninstallPackageAsync(PackageIdentity packageIdentity, INuGetProjectContext nuGetProjectContext, CancellationToken token)', validate parameter 'packageIdentity' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.NetCorePackageReferenceProject.UninstallPackageAsync(NuGet.Packaging.Core.PackageIdentity,NuGet.ProjectManagement.INuGetProjectContext,System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.Boolean}")]
83-
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'Task<NuGetProject> NetCorePackageReferenceProjectProvider.TryCreateNuGetProjectAsync(IVsProjectAdapter vsProject, ProjectProviderContext context, bool forceProjectType)', validate parameter 'vsProject' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.NetCorePackageReferenceProjectProvider.TryCreateNuGetProjectAsync(NuGet.VisualStudio.IVsProjectAdapter,NuGet.PackageManagement.VisualStudio.ProjectProviderContext,System.Boolean)~System.Threading.Tasks.Task{NuGet.ProjectManagement.NuGetProject}")]
77+
[assembly: SuppressMessage("Build", "CA1305:The behavior of 'string.Format(string, object)' could vary based on the current user's locale settings. Replace this call in 'CpsPackageReferenceProject.GetAssetsFilePathAsync(bool)' with a call to 'string.Format(IFormatProvider, string, params object[])'.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.CpsPackageReferenceProject.GetAssetsFilePathAsync(System.Boolean)~System.Threading.Tasks.Task{System.String}")]
78+
[assembly: SuppressMessage("Build", "CA1305:The behavior of 'string.Format(string, object)' could vary based on the current user's locale settings. Replace this call in 'CpsPackageReferenceProject.GetCacheFilePathAsync()' with a call to 'string.Format(IFormatProvider, string, params object[])'.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.CpsPackageReferenceProject.GetCacheFilePathAsync~System.Threading.Tasks.Task{System.String}")]
79+
[assembly: SuppressMessage("Build", "CA1825:Avoid unnecessary zero-length array allocations. Use Array.Empty<PackageReference>() instead.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.CpsPackageReferenceProject.GetInstalledPackagesAsync(System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.Collections.Generic.IEnumerable{NuGet.Packaging.PackageReference}}")]
80+
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'Task<bool> CpsPackageReferenceProject.InstallPackageAsync(string packageId, VersionRange range, INuGetProjectContext nuGetProjectContext, BuildIntegratedInstallationContext installationContext, CancellationToken token)', validate parameter 'range' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.CpsPackageReferenceProject.InstallPackageAsync(System.String,NuGet.Versioning.VersionRange,NuGet.ProjectManagement.INuGetProjectContext,NuGet.ProjectManagement.BuildIntegratedInstallationContext,System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.Boolean}")]
81+
[assembly: SuppressMessage("Build", "CA1305:The behavior of 'string.Format(string, object)' could vary based on the current user's locale settings. Replace this call in 'CpsPackageReferenceProject.InstallPackageAsync(string, VersionRange, INuGetProjectContext, BuildIntegratedInstallationContext, CancellationToken)' with a call to 'string.Format(IFormatProvider, string, params object[])'.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.CpsPackageReferenceProject.InstallPackageAsync(System.String,NuGet.Versioning.VersionRange,NuGet.ProjectManagement.INuGetProjectContext,NuGet.ProjectManagement.BuildIntegratedInstallationContext,System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.Boolean}")]
82+
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'Task<bool> CpsPackageReferenceProject.UninstallPackageAsync(PackageIdentity packageIdentity, INuGetProjectContext nuGetProjectContext, CancellationToken token)', validate parameter 'packageIdentity' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.CpsPackageReferenceProject.UninstallPackageAsync(NuGet.Packaging.Core.PackageIdentity,NuGet.ProjectManagement.INuGetProjectContext,System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.Boolean}")]
83+
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'Task<NuGetProject> CpsPackageReferenceProjectProvider.TryCreateNuGetProjectAsync(IVsProjectAdapter vsProject, ProjectProviderContext context, bool forceProjectType)', validate parameter 'vsProject' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.CpsPackageReferenceProjectProvider.TryCreateNuGetProjectAsync(NuGet.VisualStudio.IVsProjectAdapter,NuGet.PackageManagement.VisualStudio.ProjectProviderContext,System.Boolean)~System.Threading.Tasks.Task{NuGet.ProjectManagement.NuGetProject}")]
8484
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'NuGetLockService.NuGetLockService(JoinableTaskContext joinableTaskContext)', validate parameter 'joinableTaskContext' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.NuGetLockService.#ctor(Microsoft.VisualStudio.Threading.JoinableTaskContext)")]
8585
[assembly: SuppressMessage("Build", "CA1031:Modify 'CreateNuGetProjectAsync' to catch a more specific allowed exception type, or rethrow the exception.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.NuGetProjectFactory.CreateNuGetProjectAsync``1(NuGet.VisualStudio.IVsProjectAdapter,NuGet.PackageManagement.VisualStudio.ProjectProviderContext)~System.Threading.Tasks.Task{``0}")]
8686
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'Task<TProject> NuGetProjectFactory.CreateNuGetProjectAsync<TProject>(IVsProjectAdapter vsProjectAdapter, ProjectProviderContext optionalContext = null)', validate parameter 'vsProjectAdapter' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.PackageManagement.VisualStudio.NuGetProjectFactory.CreateNuGetProjectAsync``1(NuGet.VisualStudio.IVsProjectAdapter,NuGet.PackageManagement.VisualStudio.ProjectProviderContext)~System.Threading.Tasks.Task{``0}")]

src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/IDE/VSSolutionManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ public async Task<IEnumerable<NuGetProject>> GetNuGetProjectsAsync()
278278

279279
public async Task<bool> IsAllProjectsNominatedAsync()
280280
{
281-
var netCoreProjects = (await GetNuGetProjectsAsync()).OfType<NetCorePackageReferenceProject>().ToList();
281+
var netCoreProjects = (await GetNuGetProjectsAsync()).OfType<CpsPackageReferenceProject>().ToList();
282282

283283
foreach (var project in netCoreProjects)
284284
{

src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/NuGet.PackageManagement.VisualStudio.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,13 @@
124124
<Compile Include="IDE\ExtensibleSourceRepositoryProvider.cs" />
125125
<Compile Include="IInteractiveLoginProvider.cs" />
126126
<Compile Include="InteractiveLoginProvider.cs" />
127-
<Compile Include="Projects\NetCorePackageReferenceProject.cs" />
127+
<Compile Include="Projects\CpsPackageReferenceProject.cs" />
128128
<Compile Include="Projects\INuGetProjectProvider.cs" />
129129
<Compile Include="Projects\MSBuildNuGetProjectProvider.cs" />
130130
<Compile Include="Projects\ProjectJsonProjectProvider.cs" />
131131
<Compile Include="Projects\ProjectKNuGetProjectProvider.cs" />
132132
<Compile Include="Projects\ProjectSystemCache.cs" />
133-
<Compile Include="Projects\NetCorePackageReferenceProjectProvider.cs" />
133+
<Compile Include="Projects\CpsPackageReferenceProjectProvider.cs" />
134134
<Compile Include="Projects\ProjectProviderContext.cs" />
135135
<Compile Include="ProjectServices\VsProjectScriptHostService.cs" />
136136
<Compile Include="Prompts\DeprecatedFrameworkModel.cs" />

src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/NetCorePackageReferenceProject.cs renamed to src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/CpsPackageReferenceProject.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@
3030
namespace NuGet.PackageManagement.VisualStudio
3131
{
3232
/// <summary>
33-
/// Represents a project object associated with new VS "15" CPS project with package references.
33+
/// Represents a project object associated with Common Project System (CPS) project that has opt'd
34+
/// into package references. This includes, but may not be limited to, .NET Project System,
35+
/// C++/CLI (with PackageReference support) and MSIX deployment projects.
3436
/// Key feature/difference is the project restore info is pushed by nomination API and stored in
3537
/// a cache. Factory method retrieving the info from the cache should be provided.
3638
/// </summary>
37-
public class NetCorePackageReferenceProject : BuildIntegratedNuGetProject
39+
public class CpsPackageReferenceProject : BuildIntegratedNuGetProject
3840
{
3941
private const string TargetFrameworkCondition = "TargetFramework";
4042

@@ -48,7 +50,7 @@ public class NetCorePackageReferenceProject : BuildIntegratedNuGetProject
4850
private DateTime _lastTimeAssetsModified;
4951
private WeakReference<PackageSpec> _lastPackageSpec;
5052

51-
public NetCorePackageReferenceProject(
53+
public CpsPackageReferenceProject(
5254
string projectName,
5355
string projectUniqueName,
5456
string projectFullPath,

src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/NetCorePackageReferenceProjectProvider.cs renamed to src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/CpsPackageReferenceProjectProvider.cs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,27 @@
1919
namespace NuGet.PackageManagement.VisualStudio
2020
{
2121
/// <summary>
22-
/// Provides a method of creating <see cref="NetCorePackageReferenceProject"/> instance.
22+
/// Provides a method of creating <see cref="CpsPackageReferenceProject"/> instance.
2323
/// </summary>
2424
[Export(typeof(INuGetProjectProvider))]
25-
[Name(nameof(NetCorePackageReferenceProjectProvider))]
25+
[Name(nameof(CpsPackageReferenceProjectProvider))]
2626
[Microsoft.VisualStudio.Utilities.Order(After = nameof(ProjectKNuGetProjectProvider))]
27-
public class NetCorePackageReferenceProjectProvider : INuGetProjectProvider
27+
public class CpsPackageReferenceProjectProvider : INuGetProjectProvider
2828
{
2929
private static readonly string PackageReference = ProjectStyle.PackageReference.ToString();
3030

3131
private readonly IProjectSystemCache _projectSystemCache;
3232

3333
private readonly AsyncLazy<IComponentModel> _componentModel;
3434

35-
public RuntimeTypeHandle ProjectType => typeof(NetCorePackageReferenceProject).TypeHandle;
35+
public RuntimeTypeHandle ProjectType => typeof(CpsPackageReferenceProject).TypeHandle;
3636

3737
[ImportingConstructor]
38-
public NetCorePackageReferenceProjectProvider(IProjectSystemCache projectSystemCache)
38+
public CpsPackageReferenceProjectProvider(IProjectSystemCache projectSystemCache)
3939
: this(AsyncServiceProvider.GlobalProvider, projectSystemCache)
4040
{ }
4141

42-
public NetCorePackageReferenceProjectProvider(
42+
public CpsPackageReferenceProjectProvider(
4343
IAsyncServiceProvider vsServiceProvider,
4444
IProjectSystemCache projectSystemCache)
4545
{
@@ -74,37 +74,31 @@ public async Task<NuGetProject> TryCreateNuGetProjectAsync(
7474
return null;
7575
}
7676

77-
// Check if the project is not CPS capable or if it is CPS capable then it does not have TargetFramework(s), if so then return false
78-
if (!hierarchy.IsCapabilityMatch("CPS"))
77+
// Check if the project is not CPS capable or if it is CPS capable that its opt'd in PackageReferences
78+
if (!VsHierarchyUtility.IsCPSCapabilityCompliant(hierarchy) ||
79+
!VsHierarchyUtility.IsProjectCapabilityCompliant(hierarchy))
7980
{
8081
return null;
8182
}
8283

8384
var buildProperties = vsProject.BuildProperties;
8485

85-
// read MSBuild property RestoreProjectStyle, TargetFramework, and TargetFrameworks
86+
// read MSBuild property RestoreProjectStyle
8687
var restoreProjectStyle = await buildProperties.GetPropertyValueAsync(ProjectBuildProperties.RestoreProjectStyle);
87-
var targetFramework = await buildProperties.GetPropertyValueAsync(ProjectBuildProperties.TargetFramework);
88-
var targetFrameworks = await buildProperties.GetPropertyValueAsync(ProjectBuildProperties.TargetFrameworks);
8988

9089
// check for RestoreProjectStyle property is set and if not set to PackageReference then return false
9190
if (!(string.IsNullOrEmpty(restoreProjectStyle) ||
9291
restoreProjectStyle.Equals(PackageReference, StringComparison.OrdinalIgnoreCase)))
9392
{
9493
return null;
9594
}
96-
// check whether TargetFramework or TargetFrameworks property is set, else return false
97-
else if (string.IsNullOrEmpty(targetFramework) && string.IsNullOrEmpty(targetFrameworks))
98-
{
99-
return null;
100-
}
10195

10296
var fullProjectPath = vsProject.FullProjectPath;
10397
var unconfiguredProject = GetUnconfiguredProject(vsProject.Project);
10498

10599
var projectServices = new NetCoreProjectSystemServices(vsProject, await _componentModel.GetValueAsync());
106100

107-
return new NetCorePackageReferenceProject(
101+
return new CpsPackageReferenceProject(
108102
vsProject.ProjectName,
109103
vsProject.CustomUniqueName,
110104
fullProjectPath,

src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProjectProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace NuGet.PackageManagement.VisualStudio
2222
{
2323
[Export(typeof(INuGetProjectProvider))]
2424
[Name(nameof(LegacyPackageReferenceProjectProvider))]
25-
[Order(After = nameof(NetCorePackageReferenceProjectProvider))]
25+
[Order(After = nameof(CpsPackageReferenceProjectProvider))]
2626
public sealed class LegacyPackageReferenceProjectProvider : INuGetProjectProvider
2727
{
2828
private static readonly string PackageReference = ProjectStyle.PackageReference.ToString();

0 commit comments

Comments
 (0)