Skip to content

Commit

Permalink
Merge pull request #9610 from nkolev92/dev-nkolev92-AddPrunePackageRe…
Browse files Browse the repository at this point in the history
…ferenceSupport

Add PrunePackageReference support in project-system
  • Loading branch information
drewnoakes authored Dec 5, 2024
2 parents cd57e22 + 2fde796 commit 661be12
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/design-time-builds.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ CollectFrameworkReferences | NuGet | Returns non-transi
CollectNuGetAuditSuppressions | NuGet | Returns `NuGetAuditSuppress` items. Supports package restore.
CollectPackageDownloads | NuGet | Returns `PackageDownload` items. Supports package restore.
CollectPackageReferences | NuGet | Returns `PackageReference` items. Supports package restore.
CollectPrunePackageReferences | NuGet | Returns `PrunePackageReference` items. Supports package restore.
CollectResolvedCompilationReferencesDesignTime | DNPS |
CollectResolvedSDKReferencesDesignTime | SDK |
CollectSuggestedVisualStudioComponentIds | DNPS | Supports in-product acquisition (IPA).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public IReadOnlyDictionary<string, IReadOnlyList<IVsReferenceItem2>> Items
new KeyValuePair<string, IReadOnlyList<IVsReferenceItem2>>("PackageReference", ToItems(targetFrameworkInfo.PackageReferences)),
new KeyValuePair<string, IReadOnlyList<IVsReferenceItem2>>("PackageVersion", ToItems(targetFrameworkInfo.CentralPackageVersions)),
new KeyValuePair<string, IReadOnlyList<IVsReferenceItem2>>("ProjectReference", ToItems(targetFrameworkInfo.ProjectReferences)),
new KeyValuePair<string, IReadOnlyList<IVsReferenceItem2>>("PrunePackageReference", ToItems(targetFrameworkInfo.PrunePackageReferences)),
]);
return _items;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,18 @@
<RuleInjection>None</RuleInjection>
</XamlPropertyRule>

<Compile Update="ProjectSystem\Rules\CollectedPrunePackageReference.cs">
<DependentUpon>CollectedPrunePackageReference.xaml</DependentUpon>
</Compile>
<XamlPropertyRule Include="ProjectSystem\Rules\CollectedPrunePackageReference.xaml">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
<XlfInput>false</XlfInput>
<Generator>MSBuild:GenerateRuleSourceFromXaml</Generator>
<SubType>Designer</SubType>
<DataAccess>None</DataAccess>
<RuleInjection>None</RuleInjection>
</XamlPropertyRule>

<Compile Update="ProjectSystem\Rules\CollectedPackageDownload.cs">
<DependentUpon>CollectedPackageDownload.xaml</DependentUpon>
</Compile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,12 @@
This can (and should) be removed when we no longer need to support SDKs older than 8.0.400. -->
<Target Name="CollectNuGetAuditSuppressions" Returns="@(NuGetAuditSuppress)" />

<!-- This target is used to collect the PrunePackageReference items. It is defined by the .NET SDK starting in version 9.0.200, but we need this no-op
implementation when using older SDKs that don't have it; otherwise our design-time builds will fail. The NuGet.targets file in the SDK is imported
_after_ this file, and will override this implementation with the real one (when present).
This can (and should) be removed when we no longer need to support SDKs older than 9.0.200. -->
<Target Name="CollectPrunePackageReferences" Returns="@(PrunePackageReference)">

<!-- Collect any VS setup component IDs that should be installed for this project to work correctly in VS. -->
<Target Name="CollectSuggestedVisualStudioComponentIds"
Returns="@(SuggestedVisualStudioComponentId)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace Microsoft.VisualStudio.ProjectSystem.PackageRestore
CollectedPackageDownload.SchemaName,
CollectedPackageVersion.SchemaName,
CollectedNuGetAuditSuppressions.SchemaName,
CollectedPrunePackageReference.SchemaName,
CollectedPackageReference.SchemaName])]
internal class PackageRestoreConfiguredInputDataSource : ChainedProjectValueDataSourceBase<PackageRestoreConfiguredInput>, IPackageRestoreConfiguredInputDataSource
{
Expand All @@ -28,6 +29,7 @@ internal class PackageRestoreConfiguredInputDataSource : ChainedProjectValueData
.Add(CollectedPackageDownload.SchemaName) // Build
.Add(CollectedPackageVersion.SchemaName) // Build
.Add(CollectedNuGetAuditSuppressions.SchemaName) // Build
.Add(CollectedPrunePackageReference.SchemaName) // Build
.Add(CollectedPackageReference.SchemaName); // Build

private readonly IProjectSubscriptionService _projectSubscriptionService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public static ProjectRestoreInfo ToProjectRestoreInfo(IImmutableDictionary<strin
IProjectRuleSnapshot packageReferences = update.GetSnapshotOrEmpty(CollectedPackageReference.SchemaName);
IProjectRuleSnapshot packageVersions = update.GetSnapshotOrEmpty(CollectedPackageVersion.SchemaName);
IProjectRuleSnapshot nuGetAuditSuppress = update.GetSnapshotOrEmpty(CollectedNuGetAuditSuppressions.SchemaName);
IProjectRuleSnapshot prunePackageReferences = update.GetSnapshotOrEmpty(CollectedPrunePackageReference.SchemaName);
IProjectRuleSnapshot toolReferences = update.GetSnapshotOrEmpty(DotNetCliToolReference.SchemaName);

// For certain project types such as UWP, "TargetFrameworkMoniker" != the moniker that restore uses
Expand All @@ -39,6 +40,7 @@ public static ProjectRestoreInfo ToProjectRestoreInfo(IImmutableDictionary<strin
ToReferenceItems(packageReferences.Items),
ToReferenceItems(packageVersions.Items),
ToReferenceItems(nuGetAuditSuppress.Items),
ToReferenceItems(prunePackageReferences.Items),
properties);

return new ProjectRestoreInfo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ private static void LogTargetFramework(BatchLogger logger, TargetFrameworkInfo t
LogReferenceItems(logger, "Project References", targetFrameworkInfo.ProjectReferences);
LogReferenceItems(logger, "Package References", targetFrameworkInfo.PackageReferences);
LogReferenceItems(logger, "NuGet Audit Suppressions", targetFrameworkInfo.NuGetAuditSuppress);
LogReferenceItems(logger, "Prune Package References", targetFrameworkInfo.PrunePackageReferences);

// CPM typically adds a lot of items, normally the same set for all projects in the solution, and for individual projects
// many of the items aren't referenced by the project. While this is diagnostic logging, PackageVersions are particularly
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public TargetFrameworkInfo(
ImmutableArray<ReferenceItem> packageReferences,
ImmutableArray<ReferenceItem> centralPackageVersions,
ImmutableArray<ReferenceItem> nuGetAuditSuppress,
ImmutableArray<ReferenceItem> prunePackageReferences,
IImmutableDictionary<string, string> properties)
{
TargetFrameworkMoniker = targetFrameworkMoniker;
Expand All @@ -28,6 +29,7 @@ public TargetFrameworkInfo(
PackageReferences = packageReferences;
CentralPackageVersions = centralPackageVersions;
NuGetAuditSuppress = nuGetAuditSuppress;
PrunePackageReferences = prunePackageReferences;
Properties = properties;
}

Expand All @@ -45,6 +47,8 @@ public TargetFrameworkInfo(

public ImmutableArray<ReferenceItem> NuGetAuditSuppress { get; }

public ImmutableArray<ReferenceItem> PrunePackageReferences { get; }

public IImmutableDictionary<string, string> Properties { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE.md file in the project root for more information.

using System.Diagnostics.CodeAnalysis;

namespace Microsoft.VisualStudio.ProjectSystem
{
[ExcludeFromCodeCoverage]
[SuppressMessage("Style", "IDE0016:Use 'throw' expression")]
internal partial class CollectedPrunePackageReference
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE.md file in the project root for more information. -->
<Rule Name="CollectedPrunePackageReference"
PageTemplate="generic"
xmlns="http://schemas.microsoft.com/build/2009/properties">

<!-- Represents the set of <PrunePackageReference /> items that are gathered during a design-time build to be pushed to Solution Restore service -->

<Rule.DataSource>
<DataSource HasConfigurationCondition="False"
ItemType="PrunePackageReference"
MSBuildTarget="CollectPrunePackageReferences"
Persistence="ProjectFile"
SourceOfDefaultValue="AfterContext"
SourceType="TargetResults" />
</Rule.DataSource>

<StringProperty Name="Version"
Visible="false" />

</Rule>
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@
ReadOnly="True"
Visible="False" />

<StringProperty Name="RestoreEnablePackagePruning"
ReadOnly="True"
Visible="False" />

<StringProperty Name="RestoreFallbackFolders"
ReadOnly="True"
Visible="False" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@ private static class PackageRestoreRules
[Order(Order.Default)]
public static int CollectedNuGetAuditSuppressionsRule;

/// <summary>
/// Represents the design-time build items containing the versions of packages to be pruned that are passed to restore.
/// </summary>
[ExportRule(nameof(CollectedPrunePackageReference), PropertyPageContexts.ProjectSubscriptionService)]
[AppliesTo(ProjectCapability.PackageReferences)]
[Order(Order.Default)]
public static int CollectedPrunePackageReferencesRule;

/// <summary>
/// Represents the evaluation properties that are passed that are passed to restore.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,50 @@ public void ToProjectRestoreInfo_SetsNuGetAuditSuppressions()
Assert.Equal("https://cve.contoso.com/1", reference1.Name);
}

[Fact]
public void ToProjectRestoreInfo_SetsPrunePackageReferences()
{
var update = IProjectSubscriptionUpdateFactory.FromJson(
"""
{
"CurrentState": {
"CollectedPrunePackageReference": {
"Items" : {
"Newtonsoft.Json" : {
"Version" : "1.0",
},
"System.IO" : {
"Version" : "2.0",
},
"Microsoft.Extensions" : {
"Version" : "3.0"
}
}
}
}
}
""");
var result = RestoreBuilder.ToProjectRestoreInfo(update.CurrentState);

var prunePackageReferences = Assert.Single(result.TargetFrameworks).PrunePackageReferences;

Assert.Equal(3, prunePackageReferences.Length);

var reference1 = prunePackageReferences.FirstOrDefault(r => r.Name == "Newtonsoft.Json");
Assert.NotNull(reference1);
AssertContainsProperty("Version", "1.0", reference1.Properties);

var reference2 = prunePackageReferences.FirstOrDefault(r => r.Name == "System.IO");
Assert.NotNull(reference2);
AssertContainsProperty("Version", "2.0", reference2.Properties);

var reference3 = prunePackageReferences.FirstOrDefault(r => r.Name == "Microsoft.Extensions");
Assert.NotNull(reference3);
Assert.Equal("Microsoft.Extensions", reference3.Name);

AssertContainsProperty("Version", "3.0", reference3.Properties);
}

[Fact]
public void ToProjectRestoreInfo_SetsProjectReferences()
{
Expand Down

0 comments on commit 661be12

Please sign in to comment.