Skip to content

Commit 06ee0a5

Browse files
authored
Fix dotnet add package incorrectly adding PrivateAssets to PackageVersion item in CPM projects (#7258)
1 parent a42f952 commit 06ee0a5

3 files changed

Lines changed: 112 additions & 2 deletions

File tree

src/NuGet.Core/NuGet.CommandLine.XPlat/Utility/MSBuildAPIUtility.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,16 +437,16 @@ internal static ProjectRootElement GetDirectoryBuildPropsRootElement(Project pro
437437

438438
/// <summary>
439439
/// Add package name and version into the props file.
440+
/// Only version metadata belongs on PackageVersion items; asset metadata (PrivateAssets, IncludeAssets)
441+
/// belongs on the PackageReference item in the project file.
440442
/// </summary>
441443
/// <param name="itemGroup">Item group that needs to be modified in the props file.</param>
442444
/// <param name="libraryDependency">Package Dependency of the package to be added.</param>
443445
internal void AddPackageVersionIntoPropsItemGroup(ProjectItemGroupElement itemGroup,
444446
LibraryDependency libraryDependency)
445447
{
446-
// Add both package reference information and version metadata using the PACKAGE_VERSION_TYPE_TAG.
447448
var item = itemGroup.AddItem(PACKAGE_VERSION_TYPE_TAG, libraryDependency.Name);
448449
var packageVersion = AddVersionMetadata(libraryDependency, item);
449-
AddExtraMetadataToProjectItemElement(libraryDependency, item);
450450
Logger.LogInformation(string.Format(CultureInfo.CurrentCulture, Strings.Info_AddPkgAdded, libraryDependency.Name, packageVersion, itemGroup.ContainingProject.FullPath
451451
));
452452
}

test/NuGet.Core.FuncTests/NuGet.XPlat.FuncTest/XPlatAddPkgTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,5 +1755,49 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async(
17551755
Assert.True(XPlatTestUtils.ValidateReference(itemGroup, "packageX", userInputVersion));
17561756
}
17571757
}
1758+
1759+
[Fact]
1760+
public async Task AddPkg_DevelopmentDependencyWithCPM_PrivateAssetsOnlyOnPackageReference()
1761+
{
1762+
// Arrange
1763+
using var pathContext = new SimpleTestPathContext();
1764+
var projectA = XPlatTestUtils.CreateProject(ProjectName, pathContext, "net46");
1765+
var packageX = XPlatTestUtils.CreatePackage(developmentDependency: true);
1766+
1767+
// Generate Package
1768+
await SimpleTestPackageUtility.CreateFolderFeedV3Async(
1769+
pathContext.PackageSource,
1770+
PackageSaveMode.Defaultv3,
1771+
packageX);
1772+
1773+
// Create Directory.Packages.props to enable CPM
1774+
var directoryPackagesPropsPath = Path.Combine(pathContext.SolutionRoot, "Directory.Packages.props");
1775+
File.WriteAllText(directoryPackagesPropsPath,
1776+
@"<Project>
1777+
<PropertyGroup>
1778+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
1779+
</PropertyGroup>
1780+
</Project>");
1781+
1782+
var logger = new TestCommandOutputLogger(_testOutputHelper);
1783+
var packageArgs = XPlatTestUtils.GetPackageReferenceArgs(logger, packageX.Id, packageX.Version, projectA);
1784+
var commandRunner = new AddPackageReferenceCommandRunner();
1785+
1786+
// Act
1787+
var result = await commandRunner.ExecuteCommand(packageArgs, new MSBuildAPIUtility(logger, virtualProjectBuilder: null));
1788+
var projectXml = File.ReadAllText(projectA.ProjectPath);
1789+
var propsXml = File.ReadAllText(directoryPackagesPropsPath);
1790+
1791+
// Assert
1792+
Assert.Equal(0, result);
1793+
1794+
// .csproj PackageReference should have PrivateAssets
1795+
Assert.Contains("PrivateAssets", projectXml);
1796+
1797+
// Directory.Packages.props PackageVersion should NOT have PrivateAssets or IncludeAssets
1798+
Assert.Contains($"<PackageVersion Include=\"{packageX.Id}\" Version=\"{packageX.Version}\"", propsXml);
1799+
Assert.DoesNotContain("PrivateAssets", propsXml);
1800+
Assert.DoesNotContain("IncludeAssets", propsXml);
1801+
}
17581802
}
17591803
}

test/NuGet.Core.Tests/NuGet.CommandLine.Xplat.Tests/MSBuildAPIUtilityTests.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,5 +885,71 @@ public void GetResolvedVersions_WithAPackageInDirectoryPackageProps_GetsVersion(
885885
var version = result.First().TopLevelPackages.First().OriginalRequestedVersion;
886886
Assert.Equal("1.1.1", version);
887887
}
888+
889+
[PlatformFact(Platform.Windows)]
890+
public void AddPackageVersionIntoPropsFile_WithDevelopmentDependency_DoesNotAddPrivateAssets()
891+
{
892+
// Arrange
893+
using var testDirectory = TestDirectory.Create();
894+
var projectCollection = new ProjectCollection(
895+
globalProperties: null,
896+
remoteLoggers: null,
897+
loggers: null,
898+
toolsetDefinitionLocations: ToolsetDefinitionLocations.Default,
899+
maxNodeCount: 1,
900+
onlyLogCriticalEvents: false,
901+
loadProjectsReadOnly: false);
902+
903+
var projectOptions = new ProjectOptions
904+
{
905+
LoadSettings = ProjectLoadSettings.DoNotEvaluateElementsWithFalseCondition,
906+
ProjectCollection = projectCollection
907+
};
908+
909+
// Arrange Directory.Packages.props file
910+
var propsFile =
911+
@$"<Project>
912+
<PropertyGroup>
913+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
914+
</PropertyGroup>
915+
</Project>";
916+
File.WriteAllText(Path.Combine(testDirectory, "Directory.Packages.props"), propsFile);
917+
918+
// Arrange project file
919+
string projectContent =
920+
@$"<Project Sdk=""Microsoft.NET.Sdk"">
921+
<PropertyGroup>
922+
<TargetFramework>net6.0</TargetFramework>
923+
</PropertyGroup>
924+
</Project>";
925+
File.WriteAllText(Path.Combine(testDirectory, "projectA.csproj"), projectContent);
926+
var project = Project.FromFile(Path.Combine(testDirectory, "projectA.csproj"), projectOptions);
927+
928+
// Add item group to Directory.Packages.props
929+
var msObject = new MSBuildAPIUtility(logger: new TestLogger(), virtualProjectBuilder: null);
930+
var directoryBuildPropsRootElement = MSBuildAPIUtility.GetDirectoryBuildPropsRootElement(project);
931+
var propsItemGroup = directoryBuildPropsRootElement.AddItemGroup();
932+
933+
// Create a library dependency that simulates a development dependency (PrivateAssets=all)
934+
var libraryDependency = new LibraryDependency
935+
{
936+
LibraryRange = new LibraryRange(
937+
name: "X",
938+
versionRange: VersionRange.Parse("1.0.0"),
939+
typeConstraint: LibraryDependencyTarget.Package),
940+
SuppressParent = LibraryIncludeFlags.All,
941+
IncludeType = LibraryIncludeFlags.All & ~(LibraryIncludeFlags.Compile | LibraryIncludeFlags.Runtime | LibraryIncludeFlags.BuildTransitive)
942+
};
943+
944+
// Act
945+
msObject.AddPackageVersionIntoPropsItemGroup(propsItemGroup, libraryDependency);
946+
directoryBuildPropsRootElement.Save();
947+
948+
// Assert - PackageVersion should only have Version, not PrivateAssets or IncludeAssets
949+
string propsContent = File.ReadAllText(Path.Combine(testDirectory, "Directory.Packages.props"));
950+
Assert.Contains(@$"<PackageVersion Include=""X"" Version=""1.0.0"" />", propsContent);
951+
Assert.DoesNotContain("PrivateAssets", propsContent);
952+
Assert.DoesNotContain("IncludeAssets", propsContent);
953+
}
888954
}
889955
}

0 commit comments

Comments
 (0)