diff --git a/Scenarios.md b/Scenarios.md index 734f784c25..039dad9e8f 100644 --- a/Scenarios.md +++ b/Scenarios.md @@ -623,7 +623,7 @@ * should throw an error that it is not allowed -### ChocolateyUpgradeCommand [ 27 Scenario(s), 216 Observation(s) ] +### ChocolateyUpgradeCommand [ 29 Scenario(s), 221 Observation(s) ] #### when force upgrading a package @@ -903,6 +903,17 @@ * should not upgrade the minimum version dependency * should upgrade the package +#### when upgrading all packages happy path + + * should report for all installed packages + * should skip packages without upgrades + * should upgrade packages with upgrades + +#### when upgrading all packages with except + + * should report for all non skipped packages + * should skip packages in except list + #### when upgrading an existing package happy path * config should match package result name diff --git a/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs b/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs index 8cb45eb71b..8ef598d800 100644 --- a/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs @@ -2409,5 +2409,72 @@ public void should_not_have_any_packages_upgraded() Results.Count().ShouldEqual(0); } } + + [Concern(typeof(ChocolateyUpgradeCommand))] + public class when_upgrading_all_packages_happy_path : ScenariosBase + { + public override void Context() + { + base.Context(); + Configuration.PackageNames = Configuration.Input = "all"; + } + + public override void Because() + { + Results = Service.upgrade_run(Configuration); + } + + [Fact] + public void should_report_for_all_installed_packages() + { + Results.Count().ShouldEqual(3); + } + + [Fact] + public void should_upgrade_packages_with_upgrades() + { + var upgradePackageResult = Results.Where(x => x.Key == "upgradepackage").ToList(); + upgradePackageResult.Count.ShouldEqual(1, "upgradepackage must be there once"); + upgradePackageResult.First().Value.Version.ShouldEqual("1.1.0"); + } + + [Fact] + public void should_skip_packages_without_upgrades() + { + var installPackageResult = Results.Where(x => x.Key == "installpackage").ToList(); + installPackageResult.Count.ShouldEqual(1, "installpackage must be there once"); + installPackageResult.First().Value.Version.ShouldEqual("1.0.0"); + } + } + + [Concern(typeof(ChocolateyUpgradeCommand))] + public class when_upgrading_all_packages_with_except : ScenariosBase + { + public override void Context() + { + base.Context(); + Configuration.PackageNames = Configuration.Input = "all"; + Configuration.UpgradeCommand.PackageNamesToSkip = "upgradepackage,badpackage"; + } + + public override void Because() + { + Results = Service.upgrade_run(Configuration); + } + + [Fact] + public void should_report_for_all_non_skipped_packages() + { + Results.Count().ShouldEqual(1); + Results.First().Key.ShouldEqual("installpackage"); + } + + [Fact] + public void should_skip_packages_in_except_list() + { + var upgradePackageResult = Results.Where(x => x.Key == "upgradepackage").ToList(); + upgradePackageResult.Count.ShouldEqual(0, "upgradepackage should not be in the results list"); + } + } } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs index edd510f6e5..c3b1657adc 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs @@ -94,6 +94,9 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon { if (option != null) configuration.Features.CheckSumFiles = false; }) + .Add("except=", + "Except - a comma-separated list of package names that should not be upgraded when upgrading 'all'. Defaults to empty.", + option => configuration.UpgradeCommand.PackageNamesToSkip = option.remove_surrounding_quotes()) ; } @@ -137,6 +140,8 @@ choco upgrade notepadplusplus googlechrome atom 7zip -dvfy choco upgrade nodejs.install --version 0.10.35 choco upgrade git -s ""https://somewhere/out/there"" choco upgrade git -s ""https://somewhere/protected"" -u user -p pass + choco upgrade all + choco upgrade all --except=""skype,conemu"" "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); diff --git a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs index d13a1b1489..c5ca158ba2 100644 --- a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs +++ b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs @@ -363,6 +363,7 @@ public sealed class UpgradeCommandConfiguration public bool FailOnUnfound { get; set; } public bool FailOnNotInstalled { get; set; } public bool NotifyOnlyAvailableUpgrades { get; set; } + public string PackageNamesToSkip { get; set; } } [Serializable] diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 7974cb8780..b69cba6590 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -1155,13 +1155,45 @@ private void set_package_names_if_all_is_specified(ChocolateyConfiguration confi var quiet = config.QuietOutput; config.QuietOutput = true; - config.PackageNames = list_run(config).Select(p => p.Name).@join(ApplicationParameters.PackageNamesSeparator); - + var packagesToUpdate = list_run(config).Select(p => p.Name).ToList(); + + if (!string.IsNullOrWhiteSpace(config.UpgradeCommand.PackageNamesToSkip)) + { + var packagesToSkip = config.UpgradeCommand.PackageNamesToSkip + .Split(',') + .Where(item => !string.IsNullOrWhiteSpace(item)) + .Select(p => p.trim_safe()) + .ToList(); + + var unknownPackagesToSkip = packagesToSkip + .Where(p => !packagesToUpdate.Contains(p, StringComparer.OrdinalIgnoreCase)) + .ToList(); + + if (unknownPackagesToSkip.Any()) + { + this.Log().Warn(() => "Some packages specified in the 'except' list were not found in the local packages: '{0}'".format_with(string.Join(",", unknownPackagesToSkip))); + + packagesToSkip = packagesToSkip + .Where(p => !unknownPackagesToSkip.Contains(p, StringComparer.OrdinalIgnoreCase)) + .ToList(); + } + + if (packagesToSkip.Any()) + { + packagesToUpdate = packagesToUpdate + .Where(p => !packagesToSkip.Contains(p, StringComparer.OrdinalIgnoreCase)) + .ToList(); + + this.Log().Info(() => "These packages will not be upgraded because they were specified in the 'except' list: {0}".format_with(string.Join(",", packagesToSkip))); + } + } + config.QuietOutput = quiet; config.Input = input; config.Noop = noop; config.Prerelease = pre; config.Sources = sources; + config.PackageNames = packagesToUpdate.@join(ApplicationParameters.PackageNamesSeparator); if (customAction != null) customAction.Invoke(); }