Skip to content
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

9500 dotnet tool install: Add automatically tool upgrade and downgrade when specify version #31549

Closed
wants to merge 10 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,18 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually
<data name="PrereleaseAndVersionAreNotSupportedAtTheSameTime" xml:space="preserve">
<value>The --prerelease and --version options are not supported in the same command</value>
</data>
<data name="UpdateLocalToolSucceeded" xml:space="preserve">
<value>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</value>
</data>
<data name="UpdateLocaToolSucceededVersionNoChange" xml:space="preserve">
<value>Tool '{0}' is up to date (version '{1}' manifest file {2}) .</value>
</data>
<data name="UpdateToLowerVersion" xml:space="preserve">
<value>The requested version {0} is lower than existing version {1} (manifest file {2}).</value>
</data>
<data name="AllowPackageDowngradeOptionDescription" xml:space="preserve">
<value>Allow package downgrade when installing a .NET tool package.</value>
</data>
JL03-Yue marked this conversation as resolved.
Show resolved Hide resolved
<data name="CreateManifestIfNeededOptionDescription" xml:space="preserve">
<value>Create a tool manifest if one isn't found during tool installation. For information on how manifests are located, see https://aka.ms/dotnet/tools/create-manifest-if-needed</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ internal static class ToolInstallCommandParser
ArgumentHelpName = LocalizableStrings.FrameworkOptionName
};

public static readonly Option<bool> AllowPackageDowngradeOption = new Option<bool>("--allow-downgrade", LocalizableStrings.AllowPackageDowngradeOptionDescription);

public static readonly Option<bool> CreateManifestIfNeededOption = new Option<bool>("--create-manifest-if-needed", LocalizableStrings.CreateManifestIfNeededOptionDescription);

public static readonly Option<bool> PrereleaseOption = ToolSearchCommandParser.PrereleaseOption;
Expand Down Expand Up @@ -82,6 +84,7 @@ private static Command ConstructCommand()
command.AddOption(ToolCommandRestorePassThroughOptions.InteractiveRestoreOption);
command.AddOption(VerbosityOption);
command.AddOption(ArchitectureOption);
command.AddOption(AllowPackageDowngradeOption);
command.AddOption(CreateManifestIfNeededOption);

command.SetHandler((parseResult) => new ToolInstallCommand(parseResult).Execute());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ internal class ToolInstallLocalCommand : CommandBase
private readonly IReporter _reporter;

private readonly string _explicitManifestFile;
private readonly PackageId _packageId;
private readonly bool _allowPackageDowngrade;
private readonly bool _createManifestIfNeeded;

public ToolInstallLocalCommand(
Expand All @@ -38,6 +40,7 @@ public ToolInstallLocalCommand(
: base(parseResult)
{
_explicitManifestFile = parseResult.GetValue(ToolAppliedOption.ToolManifestOption);
_packageId = new PackageId(parseResult.GetValue(ToolUpdateCommandParser.PackageIdArgument));

_createManifestIfNeeded = parseResult.GetValue(ToolInstallCommandParser.CreateManifestIfNeededOption);

Expand All @@ -48,12 +51,70 @@ public ToolInstallLocalCommand(
_toolManifestEditor = toolManifestEditor ?? new ToolManifestEditor();
_localToolsResolverCache = localToolsResolverCache ?? new LocalToolsResolverCache();
_toolLocalPackageInstaller = new ToolInstallLocalInstaller(parseResult, toolPackageInstaller);
_allowPackageDowngrade = parseResult.GetValue(ToolInstallCommandParser.AllowPackageDowngradeOption);
}

public override int Execute()
{
FilePath manifestFile = GetManifestFilePath();
return Install(manifestFile);
var existingPackageWithPackageId = _toolManifestFinder.Find(manifestFile).Where(p => p.PackageId.Equals(_packageId));

if (!existingPackageWithPackageId.Any())
{
return Install(manifestFile);
}

var existingPackage = existingPackageWithPackageId.Single();
var toolDownloadedPackage = _toolLocalPackageInstaller.Install(manifestFile);

InstallLogic(existingPackage, toolDownloadedPackage, manifestFile);
return 0;
}

public int InstallLogic(ToolManifestPackage existingPackage, IToolPackage toolDownloadedPackage, FilePath manifestFile)
JL03-Yue marked this conversation as resolved.
Show resolved Hide resolved
{
if (existingPackage.Version > toolDownloadedPackage.Version && !_allowPackageDowngrade)
{
throw new GracefulException(new[]
{
string.Format(
LocalizableStrings.UpdateToLowerVersion,
toolDownloadedPackage.Version.ToNormalizedString(),
existingPackage.Version.ToNormalizedString(),
manifestFile.Value)
},
isUserError: false);
}
else if (existingPackage.Version == toolDownloadedPackage.Version)
{
_reporter.WriteLine(
string.Format(
LocalizableStrings.UpdateLocaToolSucceededVersionNoChange,
toolDownloadedPackage.Id,
existingPackage.Version.ToNormalizedString(),
manifestFile.Value));
}
else
{
_toolManifestEditor.Edit(
manifestFile,
_packageId,
toolDownloadedPackage.Version,
toolDownloadedPackage.Commands.Select(c => c.Name).ToArray());
_reporter.WriteLine(
string.Format(
LocalizableStrings.UpdateLocalToolSucceeded,
toolDownloadedPackage.Id,
existingPackage.Version.ToNormalizedString(),
toolDownloadedPackage.Version.ToNormalizedString(),
manifestFile.Value).Green());
}

_localToolsResolverCache.SaveToolPackage(
toolDownloadedPackage,
_toolLocalPackageInstaller.TargetFrameworkToInstall);

return 0;
}

public int Install(FilePath manifestFile)
JL03-Yue marked this conversation as resolved.
Show resolved Hide resolved
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading