diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyInstallCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyInstallCommand.cs index 7181b0a87e..c85ff210aa 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyInstallCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyInstallCommand.cs @@ -62,6 +62,9 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati .Add("params=|parameters=|pkgparameters=|packageparameters=|package-parameters=", "PackageParameters - Parameters to pass to the package. Defaults to unspecified.", option => configuration.PackageParameters = option.remove_surrounding_quotes()) + .Add("allowdowngrade|allow-downgrade", + "AllowDowngrade - Should an attempt at downgrading be allowed? Defaults to false.", + option => configuration.AllowDowngrade = option != null) .Add("m|sxs|sidebyside|side-by-side|allowmultiple|allow-multiple|allowmultipleversions|allow-multiple-versions", "AllowMultipleVersions - Should multiple versions of a package be installed? Defaults to false.", option => configuration.AllowMultipleVersions = option != null) diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs index 11c10bf708..ac76ae8392 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs @@ -64,6 +64,9 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon .Add("params=|parameters=|pkgparameters=|packageparameters=|package-parameters=", "PackageParameters - Parameters to pass to the package. Defaults to unspecified.", option => configuration.PackageParameters = option.remove_surrounding_quotes()) + .Add("allowdowngrade|allow-downgrade", + "AllowDowngrade - Should an attempt at downgrading be allowed? Defaults to false.", + option => configuration.AllowDowngrade = option != null) .Add("m|sxs|sidebyside|side-by-side|allowmultiple|allow-multiple|allowmultipleversions|allow-multiple-versions", "AllowMultipleVersions - Should multiple versions of a package be installed? Defaults to false.", option => configuration.AllowMultipleVersions = option != null) diff --git a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs index 2c15cfe117..424a2c44c7 100644 --- a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs +++ b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs @@ -199,6 +199,7 @@ private void append_output(StringBuilder propertyValues, string append) public string PackageParameters { get; set; } public bool IgnoreDependencies { get; set; } public bool AllowMultipleVersions { get; set; } + public bool AllowDowngrade { get; set; } public bool ForceDependencies { get; set; } /// diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 36c4b406d9..9ca2276af9 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -308,6 +308,15 @@ public ConcurrentDictionary install_run(ChocolateyConfigu version = installedPackage.Version; } + if (installedPackage != null && version != null && version < installedPackage.Version && !config.AllowMultipleVersions && !config.AllowDowngrade) + { + string logMessage = "A newer version of {0} (v{1}) is already installed.{2} Use --allow-downgrade to attempt to install older versions, or use side by side to allow multiple versions.".format_with(installedPackage.Id, installedPackage.Version, Environment.NewLine); + var nullResult = packageInstalls.GetOrAdd(packageName, new PackageResult(installedPackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id))); + nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + this.Log().Error(ChocolateyLoggers.Important, logMessage); + continue; + } + IPackage availablePackage = packageManager.SourceRepository.FindPackage(packageName, version, config.Prerelease, allowUnlisted: false); if (availablePackage == null) { @@ -463,6 +472,15 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu continue; } + if (version != null && version < installedPackage.Version && !config.AllowMultipleVersions && !config.AllowDowngrade) + { + string logMessage = "A newer version of {0} (v{1}) is already installed.{2} Use --allow-downgrade to attempt to upgrade to older versions, or use side by side to allow multiple versions.".format_with(installedPackage.Id, installedPackage.Version, Environment.NewLine); + var nullResult = packageInstalls.GetOrAdd(packageName, new PackageResult(installedPackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id))); + nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + this.Log().Error(ChocolateyLoggers.Important, logMessage); + continue; + } + var pkgInfo = _packageInfoService.get_package_information(installedPackage); bool isPinned = pkgInfo != null && pkgInfo.IsPinned; @@ -503,7 +521,7 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu var packageResult = packageInstalls.GetOrAdd(packageName, new PackageResult(availablePackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, availablePackage.Id))); - if ((installedPackage.Version > availablePackage.Version)) + if (installedPackage.Version > availablePackage.Version && !config.AllowDowngrade) { string logMessage = "{0} v{1} is newer than the most recent.{2} You must be smarter than the average bear...".format_with(installedPackage.Id, installedPackage.Version, Environment.NewLine); packageResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); @@ -553,7 +571,7 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu if (config.RegularOutput) this.Log().Info(logMessage); } - if ((availablePackage.Version > installedPackage.Version) || config.Force) + if ((availablePackage.Version > installedPackage.Version) || config.Force || (availablePackage.Version < installedPackage.Version && config.AllowDowngrade)) { if (availablePackage.Version > installedPackage.Version) {