Skip to content

Commit 686efaf

Browse files
committed
Fix issue handling transitive framework references for pruning in VS design-time builds, and add tests
1 parent 5994c16 commit 686efaf

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

src/Tasks/Microsoft.NET.Build.Tasks/GetPackagesToPrune.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,18 @@ public override int GetHashCode()
6565

6666
protected override void ExecuteCore()
6767
{
68+
69+
// Filter out transitive framework references. Normally they wouldn't be passed to this task, but in Visual Studio design-time builds
70+
// the ResolvePackageAssets and AddTransitiveFrameworkReferences targets may have already run. Filtering these references out should
71+
// avoid a bug similar to https://github.com/dotnet/sdk/issues/14641
72+
var filteredFrameworkReferences = FrameworkReferences.Where(
73+
i => i.GetMetadata("IsTransitiveFrameworkReference") is string transitiveVal && !transitiveVal.Equals("true", StringComparison.OrdinalIgnoreCase)).ToList();
74+
6875
CacheKey key = new()
6976
{
7077
TargetFrameworkIdentifier = TargetFrameworkIdentifier,
7178
TargetFrameworkVersion = TargetFrameworkVersion,
72-
FrameworkReferences = FrameworkReferences.Select(i => i.ItemSpec).ToHashSet()
79+
FrameworkReferences = filteredFrameworkReferences.Select(i => i.ItemSpec).ToHashSet()
7380
};
7481

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

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

87-
var frameworkPackages = FrameworkPackages.GetFrameworkPackages(nugetFramework, FrameworkReferences.Select(fr => fr.ItemSpec).ToArray(), TargetingPackRoot)
94+
var frameworkPackages = FrameworkPackages.GetFrameworkPackages(nugetFramework, filteredFrameworkReferences.Select(fr => fr.ItemSpec).ToArray(), TargetingPackRoot)
8895
.SelectMany(packages => packages);
8996

9097
foreach (var kvp in frameworkPackages)

test/Microsoft.NET.Build.Tests/GivenThatWeWantToResolveConflicts.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Text.Json.Nodes;
45
using System.Text.RegularExpressions;
56
using NuGet.Common;
67
using NuGet.Frameworks;
@@ -301,5 +302,55 @@ public void PlatformPackagesCanBePruned(bool prunePackages)
301302
lockFileTarget.Libraries.Should().Contain(library => library.Name.Equals("System.Text.Json", StringComparison.OrdinalIgnoreCase));
302303
}
303304
}
305+
306+
[Fact]
307+
public void TransitiveFrameworkReferencesDoNotAffectPruning()
308+
{
309+
var referencedProject = new TestProject("ReferencedProject")
310+
{
311+
TargetFrameworks = ToolsetInfo.CurrentTargetFramework,
312+
IsExe = false
313+
};
314+
referencedProject.PackageReferences.Add(new TestPackageReference("System.Text.Json", "8.0.0"));
315+
referencedProject.FrameworkReferences.Add("Microsoft.AspNetCore.App");
316+
317+
var testProject = new TestProject()
318+
{
319+
TargetFrameworks = ToolsetInfo.CurrentTargetFramework
320+
};
321+
322+
testProject.AdditionalProperties["RestoreEnablePackagePruning"] = "True";
323+
testProject.ReferencedProjects.Add(referencedProject);
324+
325+
var testAsset = _testAssetsManager.CreateTestProject(testProject);
326+
327+
new BuildCommand(testAsset).Execute().Should().Pass();
328+
329+
var getItemsCommand1 = new MSBuildCommand(testAsset, "AddPrunePackageReferences");
330+
var itemsResult1 = getItemsCommand1.Execute("-getItem:PrunePackageReference");
331+
itemsResult1.Should().Pass();
332+
333+
var items1 = ParseItemsJson(itemsResult1.StdOut);
334+
335+
var getItemsCommand2 = new MSBuildCommand(testAsset, "ResolvePackageAssets;AddTransitiveFrameworkReferences;AddPrunePackageReferences");
336+
var itemsResult2 = getItemsCommand2.Execute("-getItem:PrunePackageReference");
337+
itemsResult2.Should().Pass();
338+
339+
var items2 = ParseItemsJson(itemsResult2.StdOut);
340+
341+
items2.Should().BeEquivalentTo(items1);
342+
343+
static List<KeyValuePair<string,string>> ParseItemsJson(string json)
344+
{
345+
List<KeyValuePair<string, string>> ret = new();
346+
var root = JsonNode.Parse(json);
347+
var items = (JsonArray) root["Items"]["PrunePackageReference"];
348+
foreach (var item in items)
349+
{
350+
ret.Add(new KeyValuePair<string, string>((string)item["Identity"], (string)item["Version"]));
351+
}
352+
return ret;
353+
}
354+
}
304355
}
305356
}

0 commit comments

Comments
 (0)