Skip to content

Commit efaba6a

Browse files
authored
Ensure props/targets imports are generated correctly for aliased projects (#7203)
1 parent e0311a9 commit efaba6a

3 files changed

Lines changed: 109 additions & 16 deletions

File tree

src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/BuildAssetsUtils.cs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using System.Xml.Linq;
1212
using NuGet.Common;
1313
using NuGet.DependencyResolver;
14-
using NuGet.Frameworks;
1514
using NuGet.LibraryModel;
1615
using NuGet.Packaging;
1716
using NuGet.Packaging.Core;
@@ -494,13 +493,13 @@ public static List<MSBuildOutputFile> GetMSBuildOutputFiles(PackageSpec project,
494493
var frameworkConditions = string.Format(
495494
CultureInfo.InvariantCulture,
496495
TargetFrameworkCondition,
497-
GetMatchingFrameworkStrings(project, ridlessTarget.TargetFramework));
496+
ridlessTarget.TargetAlias);
498497

499498
// Find matching target in the original target graphs.
500499
RestoreTargetGraph targetGraph = null;
501500
foreach (RestoreTargetGraph graph in targetGraphs)
502501
{
503-
if (string.IsNullOrEmpty(graph.RuntimeIdentifier) && ridlessTarget.TargetFramework == graph.Framework)
502+
if (string.IsNullOrEmpty(graph.RuntimeIdentifier) && ridlessTarget.TargetFramework == graph.Framework && ridlessTarget.TargetAlias == graph.TargetAlias)
504503
{
505504
targetGraph = graph;
506505
break;
@@ -854,19 +853,6 @@ static IEnumerable<LockFileItem> FilterExtensions(IList<LockFileItem> items, str
854853
}
855854
}
856855

857-
private static string GetMatchingFrameworkStrings(PackageSpec spec, NuGetFramework framework)
858-
{
859-
var frameworkString = spec.TargetFrameworks.FirstOrDefault(e => e.FrameworkName.Equals(framework))?.TargetAlias;
860-
861-
// If there were no matches, use the generated name
862-
if (string.IsNullOrEmpty(frameworkString))
863-
{
864-
return framework.GetShortFolderName();
865-
}
866-
867-
return frameworkString;
868-
}
869-
870856
private static HashSet<PackageDependencyInfo> ConvertToPackageDependencyInfo(
871857
ISet<GraphItem<RemoteResolveResult>> items)
872858
{

test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommand_Aliases.cs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Linq;
66
using System.Threading.Tasks;
7+
using System.Xml.Linq;
78
using FluentAssertions;
89
using NuGet.Commands.Test;
910
using NuGet.Common;
@@ -71,6 +72,110 @@ await SimpleTestPackageUtility.CreatePackagesAsync(
7172
result.LockFile.Targets[1].Libraries[0].Name.Should().Be("y");
7273
}
7374

75+
// P1 (apple) -> X (has build/x.targets and build/x.props)
76+
// P1 (banana) -> Y (has build/y.targets and build/y.props)
77+
[Fact]
78+
public async Task RestoreCommand_WithAliasesOfSameFramework_BuildPropsAndTargetsAreIncluded()
79+
{
80+
using var pathContext = new SimpleTestPathContext();
81+
var rootProject = @"
82+
{
83+
""frameworks"": {
84+
""apple"": {
85+
""framework"": ""net10.0"",
86+
""targetAlias"": ""apple"",
87+
""dependencies"": {
88+
""x"": {
89+
""version"": ""[1.0.0,)"",
90+
""target"": ""Package"",
91+
}
92+
}
93+
},
94+
""banana"": {
95+
""framework"": ""net10.0"",
96+
""targetAlias"": ""banana"",
97+
""dependencies"": {
98+
""y"": {
99+
""version"": ""[1.0.0,)"",
100+
""target"": ""Package"",
101+
}
102+
}
103+
}
104+
}
105+
}";
106+
107+
// Create packages with build props and targets
108+
var packageX = new SimpleTestPackageContext("x", "1.0.0");
109+
packageX.AddFile("build/x.targets");
110+
packageX.AddFile("build/x.props");
111+
112+
var packageY = new SimpleTestPackageContext("y", "1.0.0");
113+
packageY.AddFile("build/y.targets");
114+
packageY.AddFile("build/y.props");
115+
116+
// Setup project
117+
var projectSpec = ProjectTestHelpers.GetPackageSpecWithProjectNameAndSpec("Project1", pathContext.SolutionRoot, rootProject);
118+
await SimpleTestPackageUtility.CreatePackagesAsync(
119+
pathContext.PackageSource,
120+
packageX,
121+
packageY);
122+
123+
// Act
124+
var result = await RunRestoreAsync(pathContext, projectSpec);
125+
126+
// Assert
127+
result.Success.Should().BeTrue();
128+
result.LockFile.Targets.Should().HaveCount(2);
129+
130+
var appleTarget = result.LockFile.GetTarget("apple", null);
131+
appleTarget.Should().NotBeNull();
132+
appleTarget.Libraries.Should().HaveCount(1);
133+
appleTarget.Libraries[0].Name.Should().Be("x");
134+
appleTarget.Libraries[0].Build.Should().Contain(item => item.Path.Equals("build/x.props"));
135+
appleTarget.Libraries[0].Build.Should().Contain(item => item.Path.Equals("build/x.targets"));
136+
137+
var bananaTarget = result.LockFile.GetTarget("banana", null);
138+
bananaTarget.Should().NotBeNull();
139+
bananaTarget.Libraries.Should().HaveCount(1);
140+
bananaTarget.Libraries[0].Name.Should().Be("y");
141+
bananaTarget.Libraries[0].Build.Should().Contain(item => item.Path.Equals("build/y.props"));
142+
bananaTarget.Libraries[0].Build.Should().Contain(item => item.Path.Equals("build/y.targets"));
143+
144+
// Validate MSBuild output files contain correct ImportGroup conditions per alias
145+
var targetsOutput = result.MSBuildOutputFiles.First(f => f.Path.EndsWith(".targets"));
146+
var propsOutput = result.MSBuildOutputFiles.First(f => f.Path.EndsWith(".props"));
147+
148+
targetsOutput.Content.Should().NotBeNull();
149+
propsOutput.Content.Should().NotBeNull();
150+
151+
var targetImportGroups = targetsOutput.Content!.Root!.Elements()
152+
.Where(e => e.Name.LocalName == "ImportGroup")
153+
.ToList();
154+
var propsImportGroups = propsOutput.Content!.Root!.Elements()
155+
.Where(e => e.Name.LocalName == "ImportGroup")
156+
.ToList();
157+
158+
// There should be an ImportGroup per alias
159+
targetImportGroups.Should().Contain(g => g.Attribute(XName.Get("Condition"))!.Value.Contains("'$(TargetFramework)' == 'apple'"));
160+
targetImportGroups.Should().Contain(g => g.Attribute(XName.Get("Condition"))!.Value.Contains("'$(TargetFramework)' == 'banana'"));
161+
162+
propsImportGroups.Should().Contain(g => g.Attribute(XName.Get("Condition"))!.Value.Contains("'$(TargetFramework)' == 'apple'"));
163+
propsImportGroups.Should().Contain(g => g.Attribute(XName.Get("Condition"))!.Value.Contains("'$(TargetFramework)' == 'banana'"));
164+
165+
// Verify the imports reference the correct packages per alias
166+
var appleTargetsGroup = targetImportGroups.First(g => g.Attribute(XName.Get("Condition"))!.Value.Contains("apple"));
167+
appleTargetsGroup.Elements().Should().Contain(e => e.Attribute(XName.Get("Project"))!.Value.Contains("x.targets"));
168+
169+
var bananaTargetsGroup = targetImportGroups.First(g => g.Attribute(XName.Get("Condition"))!.Value.Contains("banana"));
170+
bananaTargetsGroup.Elements().Should().Contain(e => e.Attribute(XName.Get("Project"))!.Value.Contains("y.targets"));
171+
172+
var applePropsGroup = propsImportGroups.First(g => g.Attribute(XName.Get("Condition"))!.Value.Contains("apple"));
173+
applePropsGroup.Elements().Should().Contain(e => e.Attribute(XName.Get("Project"))!.Value.Contains("x.props"));
174+
175+
var bananaPropsGroup = propsImportGroups.First(g => g.Attribute(XName.Get("Condition"))!.Value.Contains("banana"));
176+
bananaPropsGroup.Elements().Should().Contain(e => e.Attribute(XName.Get("Project"))!.Value.Contains("y.props"));
177+
}
178+
74179
// P (apple) -> Net472 package, with ATF, succeeds
75180
// P (banana) -> Net472 package, with ATF, fails
76181
[Fact]

test/NuGet.Core.Tests/NuGet.Commands.Test/BuildAssetsUtilsTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,7 @@ public async Task BuildAssetsUtils_GeneratePathProperty()
704704
{
705705
new LockFileTarget
706706
{
707+
TargetAlias = targetGraphs[0].TargetAlias,
707708
RuntimeIdentifier = targetGraphs[0].RuntimeIdentifier,
708709
TargetFramework = targetGraphs[0].Framework,
709710
Libraries =
@@ -813,6 +814,7 @@ public async Task BuildAssetsUtils_GeneratePathPropertyForTools(bool hasTools)
813814
{
814815
new LockFileTarget
815816
{
817+
TargetAlias = targetGraphs[0].TargetAlias,
816818
RuntimeIdentifier = targetGraphs[0].RuntimeIdentifier,
817819
TargetFramework = targetGraphs[0].Framework,
818820
Libraries =

0 commit comments

Comments
 (0)