From 3c592a9091ff8bf4f1c9e029bf53456a90fb59f7 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 6 Nov 2023 13:47:10 -0800 Subject: [PATCH 1/7] accept bare version as NuGet exact version for ,NET tools and add a test --- .../install/ParseResultExtension.cs | 21 +++++++++++++++++++ ...ToolInstallGlobalOrToolPathCommandTests.cs | 17 +++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs index 25befc5e7458..a4b10e15356c 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs @@ -1,16 +1,20 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Generic; using System.CommandLine; using System.CommandLine.Parsing; using System.Linq; +using System.Text.RegularExpressions; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.NugetSearch; using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Tools.Tool.Search; +using Newtonsoft.Json.Linq; using NuGet.Versioning; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace Microsoft.DotNet.Tools.Tool.Install { @@ -36,6 +40,14 @@ public static VersionRange GetVersionRange(this ParseResult parseResult) } VersionRange versionRange = null; + + // accept 'bare' versions and interpret 'bare' versions as NuGet exact versions + string text = packageVersion?.Trim(); + if (!string.IsNullOrEmpty(packageVersion) && IsBarePackageVersion(text)) + { + packageVersion = "[" + packageVersion + "]"; + } + if (!string.IsNullOrEmpty(packageVersion) && !VersionRange.TryParse(packageVersion, out versionRange)) { throw new GracefulException( @@ -45,5 +57,14 @@ public static VersionRange GetVersionRange(this ParseResult parseResult) } return versionRange; } + + private static bool IsBarePackageVersion (string packageVersion) + { + // Define a regular expression pattern to match the "a.b.c" format + string pattern = @"^\d+\.\d+\.\d+$"; + + // Use Regex.IsMatch to check if the input matches the pattern + return Regex.IsMatch(packageVersion, pattern); + } } } diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs index c432e84c8f04..e0c4e247d4fb 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs @@ -369,6 +369,23 @@ public void WhenRunWithValidUnlistedVersionRangeItShouldSucceed() toolUninstallCommand.Execute().Should().Pass(); } + [Fact] + public void WhenRunWithValidBareVersionItShouldInterpretAsNuGetExactVersion() + { + const string nugetSourcePath = "https://api.nuget.org/v3/index.json"; + var testDir = _testAssetsManager.CreateTestDirectory().Path; + + var toolInstallGlobalOrToolPathCommand = new DotnetCommand(Log, "tool", "install", "-g", UnlistedPackageId, "--version", "0.5.0", "--add-source", nugetSourcePath) + .WithEnvironmentVariable("DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK", "true") + .WithWorkingDirectory(testDir); + + toolInstallGlobalOrToolPathCommand.Execute().Should().Pass(); + + // Uninstall the unlisted package + var toolUninstallCommand = new DotnetCommand(Log, "tool", "uninstall", "-g", UnlistedPackageId); + toolUninstallCommand.Execute().Should().Pass(); + } + [Fact] public void WhenRunWithoutValidVersionUnlistedToolItShouldThrow() { From 85c0d6456321dde1c6e149a04c7e84a81193ba1e Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 6 Nov 2023 16:05:52 -0800 Subject: [PATCH 2/7] accept semver for versions --- .../dotnet/commands/dotnet-tool/install/ParseResultExtension.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs index a4b10e15356c..6c177f65cd8f 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs @@ -61,7 +61,7 @@ public static VersionRange GetVersionRange(this ParseResult parseResult) private static bool IsBarePackageVersion (string packageVersion) { // Define a regular expression pattern to match the "a.b.c" format - string pattern = @"^\d+\.\d+\.\d+$"; + string pattern = @"^\d+\.\d+\.\d+(-[\w\d]+(\.[\w\d]+)*)?(\+[\w\d]+(\.[\w\d]+)*)?$"; // Use Regex.IsMatch to check if the input matches the pattern return Regex.IsMatch(packageVersion, pattern); From aed3b674ad1ac52317bc7db8fdbdd395a8b4cf8f Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 7 Nov 2023 14:45:56 -0800 Subject: [PATCH 3/7] change the detection of bar version to use semver --- .../dotnet-tool/install/ParseResultExtension.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs index 6c177f65cd8f..fb7625c785fb 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs @@ -42,8 +42,7 @@ public static VersionRange GetVersionRange(this ParseResult parseResult) VersionRange versionRange = null; // accept 'bare' versions and interpret 'bare' versions as NuGet exact versions - string text = packageVersion?.Trim(); - if (!string.IsNullOrEmpty(packageVersion) && IsBarePackageVersion(text)) + if (!string.IsNullOrEmpty(packageVersion) && SemanticVersion.TryParse(packageVersion, out SemanticVersion version2)) { packageVersion = "[" + packageVersion + "]"; } @@ -57,14 +56,5 @@ public static VersionRange GetVersionRange(this ParseResult parseResult) } return versionRange; } - - private static bool IsBarePackageVersion (string packageVersion) - { - // Define a regular expression pattern to match the "a.b.c" format - string pattern = @"^\d+\.\d+\.\d+(-[\w\d]+(\.[\w\d]+)*)?(\+[\w\d]+(\.[\w\d]+)*)?$"; - - // Use Regex.IsMatch to check if the input matches the pattern - return Regex.IsMatch(packageVersion, pattern); - } } } From bea26d5ba167cd24588006daededc07cbdca1652 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 8 Nov 2023 14:22:22 -0800 Subject: [PATCH 4/7] remove excessive usings --- .../dotnet-tool/install/ParseResultExtension.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs index fb7625c785fb..c04fc4b6ebe3 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs @@ -1,20 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.Parsing; -using System.Linq; -using System.Text.RegularExpressions; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.NugetSearch; -using Microsoft.DotNet.ToolPackage; -using Microsoft.DotNet.Tools.Tool.Search; -using Newtonsoft.Json.Linq; using NuGet.Versioning; -using static System.Runtime.InteropServices.JavaScript.JSType; namespace Microsoft.DotNet.Tools.Tool.Install { From 094e1b258eef8803c225bfeb547ca50e1e9db178 Mon Sep 17 00:00:00 2001 From: JL03-Yue <59816815+JL03-Yue@users.noreply.github.com> Date: Fri, 10 Nov 2023 10:11:29 -0800 Subject: [PATCH 5/7] change SemVer to NuGetVer Co-authored-by: Andy Zivkovic --- .../dotnet/commands/dotnet-tool/install/ParseResultExtension.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs index c04fc4b6ebe3..72450cde7d70 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs @@ -32,7 +32,7 @@ public static VersionRange GetVersionRange(this ParseResult parseResult) VersionRange versionRange = null; // accept 'bare' versions and interpret 'bare' versions as NuGet exact versions - if (!string.IsNullOrEmpty(packageVersion) && SemanticVersion.TryParse(packageVersion, out SemanticVersion version2)) + if (!string.IsNullOrEmpty(packageVersion) && NuGetVersion.TryParse(packageVersion, out SemanticVersion version2)) { packageVersion = "[" + packageVersion + "]"; } From 79f37193702ee53afcdd5f644ed7ecf326d1c345 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 12 Nov 2023 15:03:49 -0800 Subject: [PATCH 6/7] resolve comments' suggestions --- .../dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs | 3 ++- .../commands/dotnet-tool/install/ParseResultExtension.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index 76fabcd7b8ff..ac176a717930 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -527,7 +527,8 @@ public async Task GetBestPackageVersionAsync(PackageId packageId, VersionRange versionRange, PackageSourceLocation packageSourceLocation = null) { - if(versionRange.MinVersion != null && versionRange.MaxVersion != null && versionRange.MinVersion == versionRange.MaxVersion) + if (versionRange.MinVersion != null && !versionRange.IsFloating && + (versionRange.MaxVersion == null || versionRange.MinVersion == versionRange.MaxVersion)) { return versionRange.MinVersion; } diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs index 72450cde7d70..44e12574cf19 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs @@ -34,7 +34,7 @@ public static VersionRange GetVersionRange(this ParseResult parseResult) // accept 'bare' versions and interpret 'bare' versions as NuGet exact versions if (!string.IsNullOrEmpty(packageVersion) && NuGetVersion.TryParse(packageVersion, out SemanticVersion version2)) { - packageVersion = "[" + packageVersion + "]"; + return new VersionRange(minVersion: new NuGetVersion(packageVersion), includeMinVersion: true, maxVersion: new NuGetVersion(packageVersion), includeMaxVersion: true, originalString: "[" + packageVersion + "]"); } if (!string.IsNullOrEmpty(packageVersion) && !VersionRange.TryParse(packageVersion, out versionRange)) From ad48dd6d30ff63979df95a8a0e3c2eaaa789192b Mon Sep 17 00:00:00 2001 From: JL03-Yue <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:37:11 -0800 Subject: [PATCH 7/7] parse the string one time Co-authored-by: Andy Zivkovic --- .../commands/dotnet-tool/install/ParseResultExtension.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs index 44e12574cf19..88a46d72e734 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs @@ -32,9 +32,9 @@ public static VersionRange GetVersionRange(this ParseResult parseResult) VersionRange versionRange = null; // accept 'bare' versions and interpret 'bare' versions as NuGet exact versions - if (!string.IsNullOrEmpty(packageVersion) && NuGetVersion.TryParse(packageVersion, out SemanticVersion version2)) + if (!string.IsNullOrEmpty(packageVersion) && NuGetVersion.TryParse(packageVersion, out NuGetVersion version2)) { - return new VersionRange(minVersion: new NuGetVersion(packageVersion), includeMinVersion: true, maxVersion: new NuGetVersion(packageVersion), includeMaxVersion: true, originalString: "[" + packageVersion + "]"); + return new VersionRange(minVersion: version2, includeMinVersion: true, maxVersion: version2, includeMaxVersion: true, originalString: "[" + packageVersion + "]"); } if (!string.IsNullOrEmpty(packageVersion) && !VersionRange.TryParse(packageVersion, out versionRange))