-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Fix version handling in dotnet add file.cs package
#50924
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
Conversation
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.
Pull Request Overview
This PR fixes version handling in the dotnet add file.cs package
command by addressing an issue where the --version
option was not properly considered when determining if a version was specified.
- Replaces the
hasVersion
boolean logic with a unifiedspecifiedVersion
string that captures both@version
syntax and--version
option values - Refactors file-based package add tests to use parameterized testing with combinatorial data to cover more command variations
- Consolidates duplicate test methods into a single helper method that generates appropriate command arguments
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
src/Cli/dotnet/Commands/Package/Add/PackageAddCommand.cs | Updates version detection logic to consider both @version syntax and --version option |
test/dotnet.Tests/CommandTests/Package/Add/GivenDotnetPackageAdd.cs | Refactors tests to use combinatorial data and shared helper method for better coverage |
@RikkiGibson @333fred @MiYanni for reviews, thanks |
: (prerelease | ||
? "*-*" | ||
: "*"); | ||
string version = specifiedVersion ?? (prerelease ? "*-*" : "*"); |
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.
fyi this will add unlisted packages as well NuGet/Home#7466
Just in case you get an issue around it.
Referencing NuGet/Home#14390 to make it easier for when NuGet starts operating on msbuild projects.
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.
So wildcards/floats will resolve unlisted versions? That's undesirable. Is this also true for regular <PackageReference />
items, or just in the CLIs' add commands?
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.
That's how floating versions work in general.
The trick is that file based add package
is using a floating version to determine the latest version, while regular add package does a separate call.
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.
while regular add package does a separate call.
So should we be doing the same for file-based apps then?
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.
Ideally yes, but the issue NuGet/Home#14390 which @nkolev92 linked tracks moving this logic to NuGet so that will resolve the problem.
@RikkiGibson @333fred @MiYanni for reviews, thanks |
bool hasVersion = _packageId.HasVersion; | ||
string? specifiedVersion = _packageId.HasVersion | ||
? _packageId.VersionRange?.OriginalString ?? string.Empty | ||
: _parseResult.GetValue(PackageAddCommandParser.VersionOption); |
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.
nit: This makes me think that we should change the VersionOption
to be a proper type instead of a string. We should be tightening these things up as we go.
{ | ||
if (!legacyForm && !fileOption) | ||
{ | ||
Log.WriteLine("Skipping invalid combination of parameters"); |
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.
nit: one thing I really love about TUnit is you can declare a specific combination of test theory parameters as an exclusion. Wish we had that here. Would be lovely to be able to use xunitv3 or something more modern.
|
||
[Fact] | ||
public void FileBasedApp_CentralPackageManagement_NoVersionSpecified_KeepExisting() | ||
[Theory, CombinatorialData] |
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.
love to see the more theory-driven samples here!
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.
There isn't a need to make a change in this PR, but, I would caution about complex use of CombinatorialData
, and potential effect on execution time of the whole suite over time. 32 cases for a theory is far from the worst in that regard--that's the most I think I saw in this PR--but, compiler tests have inadvertently created 1000 or so combinatorial cases for a single theory in the past, IIRC.
But, if we don't have a reason to think that every single combination of the arguments is exercising an interesting aspect of the system, it can be worthwhile to consider methods like pairwise testing. This can be a good supplement to determining the cases which are thought to be interesting solely based on the meaning of the respective inputs.
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.
It looks like Andrew actually implemented pairwise testing in the same library that implements CombinatorialDataAttribute: https://aarnott.github.io/Xunit.Combinatorial/docs/combinatorial-vs-pairwise.html#pairwise-testing.
bool hasVersion = _packageId.HasVersion; | ||
string? specifiedVersion = _packageId.HasVersion | ||
? _packageId.VersionRange?.OriginalString ?? string.Empty | ||
: _parseResult.GetValue(PackageAddCommandParser.VersionOption); |
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.
Is anything blocking both CmdPackageArgument
and VersionOption
specifying a version at once?
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.
Yes, there is a validator on the VersionOption for that.
public void FileBasedApp() | ||
private string[]? GetFileBasedAppArgs(bool legacyForm, bool? versionOption, bool fileOption, bool noRestore, string packageName = "Humanizer") | ||
{ | ||
if (!legacyForm && !fileOption) |
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.
Does this mean that when the "legacy form" add package
is used, it can automatically find and update Program.cs
?
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.
No, but it can specify the file as an argument (dotnet add file.cs package
) whereas the current form can specify it only as an option (dotnet package add --file file.cs
)
|
||
[Fact] | ||
public void FileBasedApp_CentralPackageManagement_NoVersionSpecified_KeepExisting() | ||
[Theory, CombinatorialData] |
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.
There isn't a need to make a change in this PR, but, I would caution about complex use of CombinatorialData
, and potential effect on execution time of the whole suite over time. 32 cases for a theory is far from the worst in that regard--that's the most I think I saw in this PR--but, compiler tests have inadvertently created 1000 or so combinatorial cases for a single theory in the past, IIRC.
But, if we don't have a reason to think that every single combination of the arguments is exercising an interesting aspect of the system, it can be worthwhile to consider methods like pairwise testing. This can be a good supplement to determining the cases which are thought to be interesting solely based on the meaning of the respective inputs.
Fixes #50913.