Skip to content

Commit

Permalink
Fix issue handling transitive framework references for pruning in VS …
Browse files Browse the repository at this point in the history
…design-time builds, and add tests
  • Loading branch information
dsplaisted committed Jan 14, 2025
1 parent 5994c16 commit 686efaf
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/Tasks/Microsoft.NET.Build.Tasks/GetPackagesToPrune.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,18 @@ public override int GetHashCode()

protected override void ExecuteCore()
{

// Filter out transitive framework references. Normally they wouldn't be passed to this task, but in Visual Studio design-time builds
// the ResolvePackageAssets and AddTransitiveFrameworkReferences targets may have already run. Filtering these references out should
// avoid a bug similar to https://github.com/dotnet/sdk/issues/14641
var filteredFrameworkReferences = FrameworkReferences.Where(
i => i.GetMetadata("IsTransitiveFrameworkReference") is string transitiveVal && !transitiveVal.Equals("true", StringComparison.OrdinalIgnoreCase)).ToList();

CacheKey key = new()
{
TargetFrameworkIdentifier = TargetFrameworkIdentifier,
TargetFrameworkVersion = TargetFrameworkVersion,
FrameworkReferences = FrameworkReferences.Select(i => i.ItemSpec).ToHashSet()
FrameworkReferences = filteredFrameworkReferences.Select(i => i.ItemSpec).ToHashSet()
};

// Cache framework package values per build
Expand All @@ -84,7 +91,7 @@ protected override void ExecuteCore()

Dictionary<string, NuGetVersion> packagesToPrune = new();

var frameworkPackages = FrameworkPackages.GetFrameworkPackages(nugetFramework, FrameworkReferences.Select(fr => fr.ItemSpec).ToArray(), TargetingPackRoot)
var frameworkPackages = FrameworkPackages.GetFrameworkPackages(nugetFramework, filteredFrameworkReferences.Select(fr => fr.ItemSpec).ToArray(), TargetingPackRoot)
.SelectMany(packages => packages);

foreach (var kvp in frameworkPackages)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
using NuGet.Common;
using NuGet.Frameworks;
Expand Down Expand Up @@ -301,5 +302,55 @@ public void PlatformPackagesCanBePruned(bool prunePackages)
lockFileTarget.Libraries.Should().Contain(library => library.Name.Equals("System.Text.Json", StringComparison.OrdinalIgnoreCase));
}
}

[Fact]
public void TransitiveFrameworkReferencesDoNotAffectPruning()
{
var referencedProject = new TestProject("ReferencedProject")
{
TargetFrameworks = ToolsetInfo.CurrentTargetFramework,
IsExe = false
};
referencedProject.PackageReferences.Add(new TestPackageReference("System.Text.Json", "8.0.0"));
referencedProject.FrameworkReferences.Add("Microsoft.AspNetCore.App");

var testProject = new TestProject()
{
TargetFrameworks = ToolsetInfo.CurrentTargetFramework
};

testProject.AdditionalProperties["RestoreEnablePackagePruning"] = "True";
testProject.ReferencedProjects.Add(referencedProject);

var testAsset = _testAssetsManager.CreateTestProject(testProject);

new BuildCommand(testAsset).Execute().Should().Pass();

var getItemsCommand1 = new MSBuildCommand(testAsset, "AddPrunePackageReferences");
var itemsResult1 = getItemsCommand1.Execute("-getItem:PrunePackageReference");
itemsResult1.Should().Pass();

var items1 = ParseItemsJson(itemsResult1.StdOut);

var getItemsCommand2 = new MSBuildCommand(testAsset, "ResolvePackageAssets;AddTransitiveFrameworkReferences;AddPrunePackageReferences");
var itemsResult2 = getItemsCommand2.Execute("-getItem:PrunePackageReference");
itemsResult2.Should().Pass();

var items2 = ParseItemsJson(itemsResult2.StdOut);

items2.Should().BeEquivalentTo(items1);

static List<KeyValuePair<string,string>> ParseItemsJson(string json)
{
List<KeyValuePair<string, string>> ret = new();
var root = JsonNode.Parse(json);
var items = (JsonArray) root["Items"]["PrunePackageReference"];
foreach (var item in items)
{
ret.Add(new KeyValuePair<string, string>((string)item["Identity"], (string)item["Version"]));
}
return ret;
}
}
}
}

0 comments on commit 686efaf

Please sign in to comment.