Skip to content

Commit 37a13e2

Browse files
author
Russell Mora
committed
Implements a subset of the functionality, support for packages.config files in the upgrade command. Also extended the tests to test the new code. I did not see any value in implementing package.config support for uninstall because the problem I am interested in solving is being able to upgrade multiple packages each with a specific version in one command. Since uninstall (generally?) doesn't require specifying a version this can be done on the uninstall command line, i.e. just give the package list to uninstall.
1 parent 6909d88 commit 37a13e2

File tree

4 files changed

+183
-24
lines changed

4 files changed

+183
-24
lines changed

Scenarios.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@
647647

648648
* should throw an error that it is not allowed
649649

650-
### ChocolateyUpgradeCommand [ 29 Scenario(s), 226 Observation(s) ]
650+
### ChocolateyUpgradeCommand [ 29 Scenario(s), 236 Observation(s) ]
651651

652652
#### when force upgrading a package
653653

@@ -960,4 +960,14 @@
960960

961961
#### when upgrading packages with packages config
962962

963-
* should throw an error that it is not allowed
963+
* should contain a message that upgradepackage with an expected specified version was not installed
964+
* should contain a warning message that it upgraded 3 out of 6 packages successfully
965+
* should have a successful package result for all but expected missing package
966+
* should install expected packages in the lib directory
967+
* should install the dependency in the lib directory
968+
* should install where install location reports
969+
* should not have a successful package result for missing package
970+
* should not have inconclusive package result for all but expected install and upgrade packages
971+
* should not have warning package result
972+
* should print out package from config file in message
973+
* should specify config file is being used in message

src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs

Lines changed: 123 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace chocolatey.tests.integration.scenarios
1717
{
1818
using System;
1919
using System.Collections.Concurrent;
20+
using System.Collections.Generic;
2021
using System.IO;
2122
using System.Linq;
2223
using System.Threading;
@@ -636,17 +637,136 @@ public override void Context()
636637
base.Context();
637638
var packagesConfig = "{0}\\context\\testing.packages.config".format_with(Scenario.get_top_level());
638639
Configuration.PackageNames = Configuration.Input = packagesConfig;
640+
Scenario.add_packages_to_source_location(Configuration, "hasdependency.1.0.0*" + Constants.PackageExtension);
641+
Scenario.add_packages_to_source_location(Configuration, "isdependency.1.0.0*" + Constants.PackageExtension);
642+
Scenario.add_packages_to_source_location(Configuration, "isexactversiondependency*" + Constants.PackageExtension);
643+
Scenario.add_packages_to_source_location(Configuration, "upgradepackage*" + Constants.PackageExtension);
644+
Configuration.UpgradeCommand.FailOnNotInstalled = false;
639645
}
640646

641647
public override void Because()
642648
{
649+
Results = Service.upgrade_run(Configuration);
643650
}
644651

645652
[Fact]
646-
[ExpectedException(typeof (ApplicationException))]
647-
public void should_throw_an_error_that_it_is_not_allowed()
653+
public void should_install_where_install_location_reports()
648654
{
649-
Results = Service.upgrade_run(Configuration);
655+
foreach (var packageResult in Results)
656+
{
657+
if (packageResult.Value.Name.is_equal_to("missingpackage")) continue;
658+
Directory.Exists(packageResult.Value.InstallLocation).ShouldBeTrue();
659+
}
660+
}
661+
662+
[Fact]
663+
public void should_install_expected_packages_in_the_lib_directory()
664+
{
665+
var packagesExpected = new List<string> { "installpackage", "hasdependency", "isdependency", "upgradepackage" };
666+
foreach (var package in packagesExpected)
667+
{
668+
var packageDir = Path.Combine(Scenario.get_top_level(), "lib", package);
669+
Directory.Exists(packageDir).ShouldBeTrue();
670+
}
671+
}
672+
673+
[Fact]
674+
public void should_install_the_dependency_in_the_lib_directory()
675+
{
676+
var packageDir = Path.Combine(Scenario.get_top_level(), "lib", "isdependency");
677+
Directory.Exists(packageDir).ShouldBeTrue();
678+
}
679+
680+
[Fact]
681+
public void should_contain_a_warning_message_that_it_upgraded_3_out_of_6_packages_successfully()
682+
{
683+
bool upgradedSuccessfully = false;
684+
foreach (var message in MockLogger.MessagesFor(LogLevel.Warn).or_empty_list_if_null())
685+
{
686+
if (message.Contains("3/6")) upgradedSuccessfully = true;
687+
}
688+
689+
upgradedSuccessfully.ShouldBeTrue();
690+
}
691+
692+
[Fact]
693+
public void should_contain_a_message_that_upgradepackage_with_an_expected_specified_version_was_not_installed()
694+
{
695+
bool expectedMessage = false;
696+
foreach (var message in MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null())
697+
{
698+
if (message.Contains("upgradepackage v1.0.0 is the latest version available based on your source")) expectedMessage = true;
699+
}
700+
701+
expectedMessage.ShouldBeTrue();
702+
}
703+
704+
[Fact]
705+
public void should_have_a_successful_package_result_for_all_but_expected_missing_package()
706+
{
707+
foreach (var packageResult in Results)
708+
{
709+
if (packageResult.Value.Name.is_equal_to("missingpackage")) continue;
710+
711+
packageResult.Value.Success.ShouldBeTrue();
712+
}
713+
}
714+
715+
[Fact]
716+
public void should_not_have_a_successful_package_result_for_missing_package()
717+
{
718+
foreach (var packageResult in Results)
719+
{
720+
if (!packageResult.Value.Name.is_equal_to("missingpackage")) continue;
721+
722+
packageResult.Value.Success.ShouldBeFalse();
723+
}
724+
}
725+
726+
[Fact]
727+
public void should_not_have_inconclusive_package_result_for_all_but_expected_install_and_upgrade_packages()
728+
{
729+
foreach (var packageResult in Results)
730+
{
731+
// These two packages don't upgrade because there is no newer version available
732+
if (packageResult.Value.Name.is_equal_to("installpackage") || packageResult.Value.Name.is_equal_to("upgradepackage"))
733+
packageResult.Value.Inconclusive.ShouldBeTrue();
734+
else
735+
packageResult.Value.Inconclusive.ShouldBeFalse();
736+
}
737+
}
738+
739+
[Fact]
740+
public void should_not_have_warning_package_result()
741+
{
742+
foreach (var packageResult in Results)
743+
{
744+
packageResult.Value.Warning.ShouldBeFalse();
745+
}
746+
}
747+
748+
[Fact]
749+
public void should_specify_config_file_is_being_used_in_message()
750+
{
751+
bool expectedMessage = false;
752+
foreach (var message in MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null())
753+
{
754+
if (message.Contains("Upgrading from config file:")) expectedMessage = true;
755+
}
756+
757+
expectedMessage.ShouldBeTrue();
758+
}
759+
760+
[Fact]
761+
public void should_print_out_package_from_config_file_in_message()
762+
{
763+
bool expectedMessage = false;
764+
foreach (var message in MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null())
765+
{
766+
if (message.Contains("installpackage")) expectedMessage = true;
767+
}
768+
769+
expectedMessage.ShouldBeTrue();
650770
}
651771
}
652772

src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,10 @@ public virtual void help_message(ChocolateyConfiguration configuration)
200200
{
201201
this.Log().Info(ChocolateyLoggers.Important, "Upgrade Command");
202202
this.Log().Info(@"
203-
Upgrades a package or a list of packages. Some may prefer to use `cup`
204-
as a shortcut for `choco upgrade`. If you do not have a package
205-
installed, upgrade will install it.
203+
Upgrades a package or a list of packages(sometimes specified as a
204+
packages.config). Some may prefer to use `cup` as a shortcut for
205+
`choco upgrade`. If you do not have a package installed, upgrade
206+
will install it.
206207
207208
NOTE: 100% compatible with older Chocolatey client (0.9.8.x and below)
208209
with options and switches. Add `-y` for previous behavior with no
@@ -212,12 +213,15 @@ prompt. In most cases you can still pass options and switches with one
212213

213214
"chocolatey".Log().Info(ChocolateyLoggers.Important, "Usage");
214215
"chocolatey".Log().Info(@"
215-
choco upgrade <pkg|all> [<pkg2> <pkgN>] [<options/switches>]
216-
cup <pkg|all> [<pkg2> <pkgN>] [<options/switches>]
216+
choco upgrade <pkg|all|packages.config> [<pkg2> <pkgN>] [<options/switches>]
217+
cup <pkg|all|packages.config> [<pkg2> <pkgN>] [<options/switches>]
217218
218219
NOTE: `all` is a special package keyword that will allow you to upgrade
219220
all currently installed packages.
220221
222+
NOTE: Any package name ending with .config is considered a
223+
'packages.config' file. Please see https://bit.ly/packages_config
224+
221225
Skip upgrading certain packages with `choco pin` or with the option
222226
`--except`.
223227
@@ -244,6 +248,25 @@ choco upgrade all
244248
245249
");
246250

251+
"chocolatey".Log().Info(ChocolateyLoggers.Important, "Packages.config");
252+
"chocolatey".Log().Info(@"
253+
Alternative to PackageName. This is a list of packages in an xml manifest for Chocolatey to upgrade. This is like the packages.config that NuGet uses except it also adds other options and switches. This can also be the path to the packages.config file if it is not in the current working directory.
254+
255+
NOTE: The filename is only required to end in .config, the name is not required to be packages.config.
256+
257+
<?xml version=""1.0"" encoding=""utf-8""?>
258+
<packages>
259+
<package id=""apackage"" />
260+
<package id=""anotherPackage"" version=""1.1"" />
261+
<package id=""chocolateytestpackage"" version=""0.1"" source=""somelocation"" />
262+
<package id=""alloptions"" version=""0.1.1""
263+
source=""https://somewhere/api/v2/"" installArguments=""""
264+
packageParameters="""" forceX86=""false"" allowMultipleVersions=""false""
265+
ignoreDependencies=""false""
266+
/>
267+
</packages>
268+
269+
");
247270

248271
"chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches");
249272
"chocolatey".Log().Info(@"

src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -664,35 +664,41 @@ public void upgrade_noop(ChocolateyConfiguration config)
664664

665665
public ConcurrentDictionary<string, PackageResult> upgrade_run(ChocolateyConfiguration config)
666666
{
667-
this.Log().Info(@"Upgrading the following packages:");
667+
this.Log().Info(is_packages_config_file(config.PackageNames) ? @"Upgrading from config file:" : @"Upgrading the following packages:");
668668
this.Log().Info(ChocolateyLoggers.Important, @"{0}".format_with(config.PackageNames));
669669

670+
var packageUpgrades = new ConcurrentDictionary<string, PackageResult>();
671+
670672
if (string.IsNullOrWhiteSpace(config.Sources))
671673
{
672674
this.Log().Error(ChocolateyLoggers.Important, @"Upgrading was NOT successful. There are no sources enabled for
673675
packages and none were passed as arguments.");
674676
Environment.ExitCode = 1;
675-
return new ConcurrentDictionary<string, PackageResult>();
677+
return packageUpgrades;
676678
}
677679

678680
this.Log().Info(@"By upgrading you accept licenses for the packages.");
679681

680-
foreach (var packageConfigFile in config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).or_empty_list_if_null().Where(p => p.EndsWith(".config")).ToList())
681-
{
682-
throw new ApplicationException("A packages.config file is only used with installs.");
683-
}
682+
get_environment_before(config, allowLogging: true);
684683

685-
Action<PackageResult> action = null;
686-
if (config.SourceType == SourceType.normal)
684+
foreach (var packageConfig in set_config_from_package_names_and_packages_config(config, packageUpgrades).or_empty_list_if_null())
687685
{
688-
action = (packageResult) => handle_package_result(packageResult, config, CommandNameType.upgrade);
689-
}
686+
Action<PackageResult> action = null;
687+
if (config.SourceType == SourceType.normal)
688+
{
689+
action = (packageResult) => handle_package_result(packageResult, packageConfig, CommandNameType.upgrade);
690+
}
690691

691-
get_environment_before(config, allowLogging: true);
692692

693-
var beforeUpgradeAction = new Action<PackageResult>(packageResult => before_package_modify(packageResult, config));
694-
var packageUpgrades = perform_source_runner_function(config, r => r.upgrade_run(config, action, beforeUpgradeAction));
695-
693+
var beforeUpgradeAction = new Action<PackageResult>(packageResult => before_package_modify(packageResult, packageConfig));
694+
var results = perform_source_runner_function(config, r => r.upgrade_run(packageConfig, action, beforeUpgradeAction));
695+
696+
foreach (var result in results)
697+
{
698+
packageUpgrades.GetOrAdd(result.Key, result.Value);
699+
}
700+
}
701+
696702
var upgradeFailures = report_action_summary(packageUpgrades, "upgraded");
697703
if (upgradeFailures != 0 && Environment.ExitCode == 0)
698704
{

0 commit comments

Comments
 (0)