-
Notifications
You must be signed in to change notification settings - Fork 694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add package cli support for CPM projects #4681
Conversation
@@ -26,7 +26,7 @@ public static void AddOrUpdateDependency(PackageSpec spec, PackageDependency dep | |||
|
|||
if (!existing.Any()) | |||
{ | |||
AddDependency(spec.Dependencies, dependency.Id, range); | |||
AddDependency(spec.Dependencies, dependency.Id, range, spec.RestoreMetadata?.CentralPackageVersionsEnabled ?? false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -253,6 +253,102 @@ public void AddOrUpdateDependency_ToSpecificFrameworks_AddsNewDependency() | |||
spec.TargetFrameworks[1].Dependencies[0].LibraryRange.VersionRange.MinVersion); | |||
} | |||
|
|||
[Fact] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...uGet.CommandLine.XPlat/Commands/PackageReferenceCommands/AddPackageReferenceCommandRunner.cs
Outdated
Show resolved
Hide resolved
...uGet.CommandLine.XPlat/Commands/PackageReferenceCommands/AddPackageReferenceCommandRunner.cs
Outdated
Show resolved
Hide resolved
src/NuGet.Core/NuGet.CommandLine.XPlat/Utility/MSBuildAPIUtility.cs
Outdated
Show resolved
Hide resolved
src/NuGet.Core/NuGet.CommandLine.XPlat/Utility/MSBuildAPIUtility.cs
Outdated
Show resolved
Hide resolved
AddPackageReferenceIntoPropsItemGroup(propsItemGroup, libraryDependency); | ||
|
||
// Save the updated props file. | ||
directoryBuildPropsRootElement.Save(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm very curious if formatting is preserved. I think there might be something special we have to do to get the MSBuild APIs to do this. Can you test it out with a Directory.Packages.props that has some special formatting like:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<!-- Does the Version attribute on the new line get preserved when we update it? -->
<PackageVersion Include="SomePackage"
Version="1.0.0" />
</ItemGroup>
</Project>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are no longer updating the package version in the props file and rather adding a VersionOverride attribute to the project file instead, I think this no longer needs to be addressed. But please let me know if there are similar concerns with updating the VersionOverride attribute (I don't think there are because we are updating the project file not the props file, but I could be wrong).
EDIT: after discussion during our PR review meeting, we decided that this was still an issue that needed to be investigated and documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After further investigation, it seems that formatting is not preserved in the Directory.Packages.props file when something is modified (ex: a PackageVersion is added). I remember you mentioned that there is a flag that you can set in order to preserve the formatting, where might I be able to find that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using ProjectRootElement.PreserveFormatting
to preserve formatting. I didn't try this API :)
…ce of Directory.Packages.Props file
…ce of Directory.Packages.Props file
…ate package scenario.
… functional tests
a47da65
to
2be0195
Compare
src/NuGet.Core/NuGet.CommandLine.XPlat/Utility/MSBuildAPIUtility.cs
Outdated
Show resolved
Hide resolved
{ | ||
// Only add the package reference information using the PACKAGE_REFERENCE_TYPE_TAG. | ||
ProjectItemElement item = itemGroup.AddItem(PACKAGE_REFERENCE_TYPE_TAG, libraryDependency.Name); | ||
string packageVersion = "No package version added because this project is onboarded to CPM"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding strings to the resources file so that they can be localized. We can add a new entry in the resource file for CPM projects. For example, info : Adding PackageReference for package 'Newtonsoft.Json' into project 'C:\Users\user1\source\repos\ConsoleApp9\ConsoleApp9\ConsoleApp9.csproj' and Version into the Directory.Packages.Props file
src/NuGet.Core/NuGet.CommandLine.XPlat/Utility/MSBuildAPIUtility.cs
Outdated
Show resolved
Hide resolved
src/NuGet.Core/NuGet.CommandLine.XPlat/Utility/MSBuildAPIUtility.cs
Outdated
Show resolved
Hide resolved
There is another scenario we should consider. When add package command is executed with --no-restore switch then we should account for CPM onboarded project. We can also add a test for this scenario. Lines 35 to 62 in 84e277c
|
{ | ||
// Get the Directory.Packages.props path. | ||
string directoryPackagesPropsPath = project.GetPropertyValue("DirectoryPackagesPropsPath"); | ||
Logger.LogInformation("Modifying the Directory.Packages.props file at: " + directoryPackagesPropsPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using resource file for managing strings. The advantage is that the strings in the resource file will be localized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to expand on @kartheekp-ms's suggestion, the rule is that every string that is user facing should be localized, and come from a resource file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A suggestion for the message would be Modifying {0}
.
It'll be obvious from the name that it's a directory.build.props
else | ||
{ | ||
// MOdify the project file with version override. | ||
UpdatePackageReferenceItemsWithVersionOverride(project, libraryDependency); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should pass existingPackageReferences
to this method to avoid computing package references again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
existingPackageReferences
is only in a specific project I believe, whereas I am trying to search the whole solution for existing package references. Please let me know if I am misinterpreting that though.
if (packageVersion == null) | ||
{ | ||
// Modifying the props file if project is onboarded to CPM. | ||
AddPackageVersionIntoItemGroupCPM(project, libraryDependency); | ||
//Modify the project file. | ||
AddPackageReferenceIntoItemGroupCPM(itemGroup, libraryDependency); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should split this logic into two categories.
if (packageVersion == null)
{
// add package version to the props file.
}
if (!existingPackageReferences.Any())
{
// add package reference to the csproj file
// add the version override only if package version in the props file is different from the version passed to the add package command.
}
else
{
// add/update version override for the existing package references
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused as to what is being proposed. Is the change meant to be for all the if/else branches present?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did one quick pass.
I'll a more in depth review once the spec is updated so I know what to review :D
AddPackageReferenceIntoItemGroup(itemGroup, libraryDependency); | ||
if (!existingPackageReferences.Any()) | ||
{ | ||
//Modify the project file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of these seem like helper comments but sometimes add clutter, especially when they are describe 1 method call.
/// </summary> | ||
/// <param name="libraryDependency">Package Dependency of the package to be added.</param> | ||
/// <param name="item">Item to add the metadata to.</param> | ||
private void AddExtraMetadata(LibraryDependency libraryDependency, ProjectItemElement item) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming: Probably want to call out what metadata that is.
Example: AddFlagsMetadata.
{ | ||
// Get the Directory.Packages.props path. | ||
string directoryPackagesPropsPath = project.GetPropertyValue("DirectoryPackagesPropsPath"); | ||
Logger.LogInformation("Modifying the Directory.Packages.props file at: " + directoryPackagesPropsPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to expand on @kartheekp-ms's suggestion, the rule is that every string that is user facing should be localized, and come from a resource file.
{ | ||
// Get the Directory.Packages.props path. | ||
string directoryPackagesPropsPath = project.GetPropertyValue("DirectoryPackagesPropsPath"); | ||
Logger.LogInformation("Modifying the Directory.Packages.props file at: " + directoryPackagesPropsPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A suggestion for the message would be Modifying {0}
.
It'll be obvious from the name that it's a directory.build.props
Closing this PR as the design spec has changed. |
Bug
Fixes: NuGet/Home#11890
Regression? No.
Description
This feature is based on the design spec: NuGet/Home#11873. The goal was to allow the
dotnet add package
command to be executed for projects that were onboarded to CPM. Previously, the command threw a NU1008 error whenever packages were attempted to be added to projects onboarded to CPM. However, with this change users will now be able to add or update package references in projects onboarded to CPM.Directory.Packages.props
files and project files are now modified accordingly whenever a package is added/updated.PR Checklist
PR has a meaningful title
PR has a linked issue.
Described changes
Tests
Documentation