Skip to content

Commit 4ef0a40

Browse files
author
Russell Mora
committed
(GH-533) Support packages.config file in upgrade
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 d56b4fd commit 4ef0a40

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
@@ -649,7 +649,7 @@
649649

650650
* should throw an error that it is not allowed
651651

652-
### ChocolateyUpgradeCommand [ 36 Scenario(s), 295 Observation(s) ]
652+
### ChocolateyUpgradeCommand [ 36 Scenario(s), 305 Observation(s) ]
653653

654654
#### when force upgrading a package
655655

@@ -1052,4 +1052,14 @@
10521052

10531053
#### when upgrading packages with packages config
10541054

1055-
* should throw an error that it is not allowed
1055+
* should contain a message that upgradepackage with an expected specified version was not installed
1056+
* should contain a warning message that it upgraded 3 out of 6 packages successfully
1057+
* should have a successful package result for all but expected missing package
1058+
* should install expected packages in the lib directory
1059+
* should install the dependency in the lib directory
1060+
* should install where install location reports
1061+
* should not have a successful package result for missing package
1062+
* should not have inconclusive package result for all but expected install and upgrade packages
1063+
* should not have warning package result
1064+
* should print out package from config file in message
1065+
* 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
@@ -18,6 +18,7 @@ namespace chocolatey.tests.integration.scenarios
1818
{
1919
using System;
2020
using System.Collections.Concurrent;
21+
using System.Collections.Generic;
2122
using System.IO;
2223
using System.Linq;
2324
using System.Threading;
@@ -1204,17 +1205,136 @@ public override void Context()
12041205
base.Context();
12051206
var packagesConfig = "{0}\\context\\testing.packages.config".format_with(Scenario.get_top_level());
12061207
Configuration.PackageNames = Configuration.Input = packagesConfig;
1208+
Scenario.add_packages_to_source_location(Configuration, "hasdependency.1.0.0*" + Constants.PackageExtension);
1209+
Scenario.add_packages_to_source_location(Configuration, "isdependency.1.0.0*" + Constants.PackageExtension);
1210+
Scenario.add_packages_to_source_location(Configuration, "isexactversiondependency*" + Constants.PackageExtension);
1211+
Scenario.add_packages_to_source_location(Configuration, "upgradepackage*" + Constants.PackageExtension);
1212+
Configuration.UpgradeCommand.FailOnNotInstalled = false;
12071213
}
12081214

12091215
public override void Because()
12101216
{
1217+
Results = Service.upgrade_run(Configuration);
12111218
}
12121219

12131220
[Fact]
1214-
[ExpectedException(typeof(ApplicationException))]
1215-
public void should_throw_an_error_that_it_is_not_allowed()
1221+
public void should_install_where_install_location_reports()
12161222
{
1217-
Results = Service.upgrade_run(Configuration);
1223+
foreach (var packageResult in Results)
1224+
{
1225+
if (packageResult.Value.Name.is_equal_to("missingpackage")) continue;
1226+
Directory.Exists(packageResult.Value.InstallLocation).ShouldBeTrue();
1227+
}
1228+
}
1229+
1230+
[Fact]
1231+
public void should_install_expected_packages_in_the_lib_directory()
1232+
{
1233+
var packagesExpected = new List<string> { "installpackage", "hasdependency", "isdependency", "upgradepackage" };
1234+
foreach (var package in packagesExpected)
1235+
{
1236+
var packageDir = Path.Combine(Scenario.get_top_level(), "lib", package);
1237+
Directory.Exists(packageDir).ShouldBeTrue();
1238+
}
1239+
}
1240+
1241+
[Fact]
1242+
public void should_install_the_dependency_in_the_lib_directory()
1243+
{
1244+
var packageDir = Path.Combine(Scenario.get_top_level(), "lib", "isdependency");
1245+
Directory.Exists(packageDir).ShouldBeTrue();
1246+
}
1247+
1248+
[Fact]
1249+
public void should_contain_a_warning_message_that_it_upgraded_3_out_of_6_packages_successfully()
1250+
{
1251+
bool upgradedSuccessfully = false;
1252+
foreach (var message in MockLogger.MessagesFor(LogLevel.Warn).or_empty_list_if_null())
1253+
{
1254+
if (message.Contains("3/6")) upgradedSuccessfully = true;
1255+
}
1256+
1257+
upgradedSuccessfully.ShouldBeTrue();
1258+
}
1259+
1260+
[Fact]
1261+
public void should_contain_a_message_that_upgradepackage_with_an_expected_specified_version_was_not_installed()
1262+
{
1263+
bool expectedMessage = false;
1264+
foreach (var message in MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null())
1265+
{
1266+
if (message.Contains("upgradepackage v1.0.0 is the latest version available based on your source")) expectedMessage = true;
1267+
}
1268+
1269+
expectedMessage.ShouldBeTrue();
1270+
}
1271+
1272+
[Fact]
1273+
public void should_have_a_successful_package_result_for_all_but_expected_missing_package()
1274+
{
1275+
foreach (var packageResult in Results)
1276+
{
1277+
if (packageResult.Value.Name.is_equal_to("missingpackage")) continue;
1278+
1279+
packageResult.Value.Success.ShouldBeTrue();
1280+
}
1281+
}
1282+
1283+
[Fact]
1284+
public void should_not_have_a_successful_package_result_for_missing_package()
1285+
{
1286+
foreach (var packageResult in Results)
1287+
{
1288+
if (!packageResult.Value.Name.is_equal_to("missingpackage")) continue;
1289+
1290+
packageResult.Value.Success.ShouldBeFalse();
1291+
}
1292+
}
1293+
1294+
[Fact]
1295+
public void should_not_have_inconclusive_package_result_for_all_but_expected_install_and_upgrade_packages()
1296+
{
1297+
foreach (var packageResult in Results)
1298+
{
1299+
// These two packages don't upgrade because there is no newer version available
1300+
if (packageResult.Value.Name.is_equal_to("installpackage") || packageResult.Value.Name.is_equal_to("upgradepackage"))
1301+
packageResult.Value.Inconclusive.ShouldBeTrue();
1302+
else
1303+
packageResult.Value.Inconclusive.ShouldBeFalse();
1304+
}
1305+
}
1306+
1307+
[Fact]
1308+
public void should_not_have_warning_package_result()
1309+
{
1310+
foreach (var packageResult in Results)
1311+
{
1312+
packageResult.Value.Warning.ShouldBeFalse();
1313+
}
1314+
}
1315+
1316+
[Fact]
1317+
public void should_specify_config_file_is_being_used_in_message()
1318+
{
1319+
bool expectedMessage = false;
1320+
foreach (var message in MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null())
1321+
{
1322+
if (message.Contains("Upgrading from config file:")) expectedMessage = true;
1323+
}
1324+
1325+
expectedMessage.ShouldBeTrue();
1326+
}
1327+
1328+
[Fact]
1329+
public void should_print_out_package_from_config_file_in_message()
1330+
{
1331+
bool expectedMessage = false;
1332+
foreach (var message in MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null())
1333+
{
1334+
if (message.Contains("installpackage")) expectedMessage = true;
1335+
}
1336+
1337+
expectedMessage.ShouldBeTrue();
12181338
}
12191339
}
12201340

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

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,10 @@ public virtual void help_message(ChocolateyConfiguration configuration)
222222
{
223223
this.Log().Info(ChocolateyLoggers.Important, "Upgrade Command");
224224
this.Log().Info(@"
225-
Upgrades a package or a list of packages. Some may prefer to use `cup`
226-
as a shortcut for `choco upgrade`. If you do not have a package
227-
installed, upgrade will install it.
225+
Upgrades a package or a list of packages(sometimes specified as a
226+
packages.config). Some may prefer to use `cup` as a shortcut for
227+
`choco upgrade`. If you do not have a package installed, upgrade
228+
will install it.
228229
229230
NOTE: 100% compatible with older Chocolatey client (0.9.8.x and below)
230231
with options and switches. Add `-y` for previous behavior with no
@@ -234,12 +235,15 @@ prompt. In most cases you can still pass options and switches with one
234235

235236
"chocolatey".Log().Info(ChocolateyLoggers.Important, "Usage");
236237
"chocolatey".Log().Info(@"
237-
choco upgrade <pkg|all> [<pkg2> <pkgN>] [<options/switches>]
238-
cup <pkg|all> [<pkg2> <pkgN>] [<options/switches>]
238+
choco upgrade <pkg|all|packages.config> [<pkg2> <pkgN>] [<options/switches>]
239+
cup <pkg|all|packages.config> [<pkg2> <pkgN>] [<options/switches>]
239240
240241
NOTE: `all` is a special package keyword that will allow you to upgrade
241242
all currently installed packages.
242243
244+
NOTE: Any package name ending with .config is considered a
245+
'packages.config' file. Please see https://bit.ly/packages_config
246+
243247
Skip upgrading certain packages with `choco pin` or with the option
244248
`--except`.
245249
@@ -266,6 +270,25 @@ choco upgrade all
266270
267271
");
268272

273+
"chocolatey".Log().Info(ChocolateyLoggers.Important, "Packages.config");
274+
"chocolatey".Log().Info(@"
275+
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.
276+
277+
NOTE: The filename is only required to end in .config, the name is not required to be packages.config.
278+
279+
<?xml version=""1.0"" encoding=""utf-8""?>
280+
<packages>
281+
<package id=""apackage"" />
282+
<package id=""anotherPackage"" version=""1.1"" />
283+
<package id=""chocolateytestpackage"" version=""0.1"" source=""somelocation"" />
284+
<package id=""alloptions"" version=""0.1.1""
285+
source=""https://somewhere/api/v2/"" installArguments=""""
286+
packageParameters="""" forceX86=""false"" allowMultipleVersions=""false""
287+
ignoreDependencies=""false""
288+
/>
289+
</packages>
290+
291+
");
269292

270293
"chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches");
271294
"chocolatey".Log().Info(@"

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

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

685685
public ConcurrentDictionary<string, PackageResult> upgrade_run(ChocolateyConfiguration config)
686686
{
687-
this.Log().Info(@"Upgrading the following packages:");
687+
this.Log().Info(is_packages_config_file(config.PackageNames) ? @"Upgrading from config file:" : @"Upgrading the following packages:");
688688
this.Log().Info(ChocolateyLoggers.Important, @"{0}".format_with(config.PackageNames));
689689

690+
var packageUpgrades = new ConcurrentDictionary<string, PackageResult>();
691+
690692
if (string.IsNullOrWhiteSpace(config.Sources))
691693
{
692694
this.Log().Error(ChocolateyLoggers.Important, @"Upgrading was NOT successful. There are no sources enabled for
693695
packages and none were passed as arguments.");
694696
Environment.ExitCode = 1;
695-
return new ConcurrentDictionary<string, PackageResult>();
697+
return packageUpgrades;
696698
}
697699

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

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

705-
Action<PackageResult> action = null;
706-
if (config.SourceType == SourceType.normal)
704+
foreach (var packageConfig in set_config_from_package_names_and_packages_config(config, packageUpgrades).or_empty_list_if_null())
707705
{
708-
action = (packageResult) => handle_package_result(packageResult, config, CommandNameType.upgrade);
709-
}
706+
Action<PackageResult> action = null;
707+
if (config.SourceType == SourceType.normal)
708+
{
709+
action = (packageResult) => handle_package_result(packageResult, packageConfig, CommandNameType.upgrade);
710+
}
710711

711-
get_environment_before(config, allowLogging: true);
712712

713-
var beforeUpgradeAction = new Action<PackageResult>(packageResult => before_package_modify(packageResult, config));
714-
var packageUpgrades = perform_source_runner_function(config, r => r.upgrade_run(config, action, beforeUpgradeAction));
715-
713+
var beforeUpgradeAction = new Action<PackageResult>(packageResult => before_package_modify(packageResult, packageConfig));
714+
var results = perform_source_runner_function(config, r => r.upgrade_run(packageConfig, action, beforeUpgradeAction));
715+
716+
foreach (var result in results)
717+
{
718+
packageUpgrades.GetOrAdd(result.Key, result.Value);
719+
}
720+
}
721+
716722
var upgradeFailures = report_action_summary(packageUpgrades, "upgraded");
717723
if (upgradeFailures != 0 && Environment.ExitCode == 0)
718724
{

0 commit comments

Comments
 (0)