From 515c69575137ce833076f8d658c1126ceff1797a Mon Sep 17 00:00:00 2001 From: Richard J Foster Date: Fri, 4 Dec 2015 14:35:55 -0500 Subject: [PATCH 01/14] (GH-268)(spec) Add scenarios verifying powershell script execution. While there appeared to be verification in the noop scenario, there did not appear to be any verification in the regular case. These spec items verify that the encapsulated package script was run by examining the script output. --- .../scenarios/InstallScenarios.cs | 7 +++++++ .../scenarios/UninstallScenarios.cs | 6 ++++++ .../scenarios/UpgradeScenarios.cs | 12 ++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs b/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs index 297a5dd109..60f73bb1b4 100644 --- a/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs @@ -15,6 +15,7 @@ namespace chocolatey.tests.integration.scenarios { + using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; @@ -314,6 +315,12 @@ public void should_have_a_version_of_one_dot_zero_dot_zero() { packageResult.Version.ShouldEqual("1.0.0"); } + + [Fact] + public void should_have_executed_chocolateyInstall_script() + { + MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.Contains("installpackage v1.0.0 has been installed")).ShouldBeTrue("Installpackage info message not seen. Info messages that were seen: {0}".format_with(string.Join(Environment.NewLine, MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null()))); + } } [Concern(typeof(ChocolateyInstallCommand))] diff --git a/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs b/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs index ef3bf5e7fb..ae7d19b2fb 100644 --- a/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs @@ -219,6 +219,12 @@ public void config_should_match_package_result_name() { packageResult.Name.ShouldEqual(Configuration.PackageNames); } + + [Fact] + public void should_have_executed_chocolateyUninstall_script() + { + MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.EndsWith("installpackage 1.0.0 Uninstalled")).ShouldBeTrue(); + } } [Concern(typeof (ChocolateyUninstallCommand))] diff --git a/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs b/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs index bc06141b95..15f455aaf0 100644 --- a/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs @@ -302,6 +302,18 @@ public void should_match_the_upgrade_version_of_one_dot_one_dot_zero() { _packageResult.Version.ShouldEqual("1.1.0"); } + + [Fact] + public void should_not_have_executed_chocolateyUninstall_script_for_original_package() + { + MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.EndsWith("upgradepackage 1.0.0 Uninstalled")).ShouldBeFalse(); + } + + [Fact] + public void should_have_executed_chocolateyInstall_script_for_new_package() + { + MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.EndsWith("upgradepackage 1.1.0 Installed")).ShouldBeTrue(); + } } [Concern(typeof (ChocolateyUpgradeCommand))] From 4c8190baaebf3d062ab60173aa14c59c13df7c31 Mon Sep 17 00:00:00 2001 From: Richard J Foster Date: Sun, 19 Jul 2015 13:56:35 -0400 Subject: [PATCH 02/14] (GH-268) Add chocolateyBeforeModify.ps1 script to test packages. If we are going to verify script execution, it needs to be included in the test packages. --- .../chocolatey.tests.integration.csproj | 9 +++++++++ .../1.0.0/tools/chocolateyBeforeModify.ps1 | 1 + .../1.0.0/tools/chocolateyBeforeModify.ps1 | 1 + .../1.1.0/tools/chocolateyBeforeModify.ps1 | 1 + 4 files changed, 12 insertions(+) create mode 100644 src/chocolatey.tests.integration/context/installpackage/1.0.0/tools/chocolateyBeforeModify.ps1 create mode 100644 src/chocolatey.tests.integration/context/upgradepackage/1.0.0/tools/chocolateyBeforeModify.ps1 create mode 100644 src/chocolatey.tests.integration/context/upgradepackage/1.1.0/tools/chocolateyBeforeModify.ps1 diff --git a/src/chocolatey.tests.integration/chocolatey.tests.integration.csproj b/src/chocolatey.tests.integration/chocolatey.tests.integration.csproj index b8a813b35a..b6af2929de 100644 --- a/src/chocolatey.tests.integration/chocolatey.tests.integration.csproj +++ b/src/chocolatey.tests.integration/chocolatey.tests.integration.csproj @@ -225,6 +225,9 @@ Always + + Always + Always @@ -327,6 +330,9 @@ Always + + Always + Always @@ -345,6 +351,9 @@ Always + + Always + Always diff --git a/src/chocolatey.tests.integration/context/installpackage/1.0.0/tools/chocolateyBeforeModify.ps1 b/src/chocolatey.tests.integration/context/installpackage/1.0.0/tools/chocolateyBeforeModify.ps1 new file mode 100644 index 0000000000..af5bb142e8 --- /dev/null +++ b/src/chocolatey.tests.integration/context/installpackage/1.0.0/tools/chocolateyBeforeModify.ps1 @@ -0,0 +1 @@ +Write-Output "$env:PackageName $env:PackageVersion Before Modification" \ No newline at end of file diff --git a/src/chocolatey.tests.integration/context/upgradepackage/1.0.0/tools/chocolateyBeforeModify.ps1 b/src/chocolatey.tests.integration/context/upgradepackage/1.0.0/tools/chocolateyBeforeModify.ps1 new file mode 100644 index 0000000000..af5bb142e8 --- /dev/null +++ b/src/chocolatey.tests.integration/context/upgradepackage/1.0.0/tools/chocolateyBeforeModify.ps1 @@ -0,0 +1 @@ +Write-Output "$env:PackageName $env:PackageVersion Before Modification" \ No newline at end of file diff --git a/src/chocolatey.tests.integration/context/upgradepackage/1.1.0/tools/chocolateyBeforeModify.ps1 b/src/chocolatey.tests.integration/context/upgradepackage/1.1.0/tools/chocolateyBeforeModify.ps1 new file mode 100644 index 0000000000..af5bb142e8 --- /dev/null +++ b/src/chocolatey.tests.integration/context/upgradepackage/1.1.0/tools/chocolateyBeforeModify.ps1 @@ -0,0 +1 @@ +Write-Output "$env:PackageName $env:PackageVersion Before Modification" \ No newline at end of file From bff713cc6a23eb87de8fdd56da06e8e78d06ad97 Mon Sep 17 00:00:00 2001 From: Richard J Foster Date: Wed, 9 Dec 2015 10:19:50 -0500 Subject: [PATCH 03/14] (GH-268) Extract method to provide folder information for package. There were a several places with functionally identical code to locate the installation folder for a package. When the new pre-modification script gets added the same functionality will be needed again. Refactored into a method to eliminate additional duplicate. --- .../services/NugetService.cs | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 45ca8c131c..4e464bbb5e 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -744,16 +744,30 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu return packageInstalls; } - public void ensure_package_files_have_compatible_attributes(ChocolateyConfiguration config, IPackage installedPackage, ChocolateyPackageInformation pkgInfo) + private string get_install_directory(ChocolateyConfiguration config, IPackage installedPackage) { - var installDirectory = _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id); + var pathResolver = NugetCommon.GetPathResolver(config, NugetCommon.GetNuGetFileSystem(config, _nugetLogger)); + var installDirectory = pathResolver.GetInstallPath(installedPackage); if (!_fileSystem.directory_exists(installDirectory)) { - var pathResolver = new ChocolateyPackagePathResolver(NugetCommon.GetNuGetFileSystem(config, _nugetLogger), useSideBySidePaths: true); - installDirectory = pathResolver.GetInstallPath(installedPackage); - if (!_fileSystem.directory_exists(installDirectory)) return; + var chocoPathResolver = pathResolver as ChocolateyPackagePathResolver; + if (chocoPathResolver != null) + { + chocoPathResolver.UseSideBySidePaths = !chocoPathResolver.UseSideBySidePaths; + installDirectory = chocoPathResolver.GetInstallPath(installedPackage); + } + + if (!_fileSystem.directory_exists(installDirectory)) return null; } + return installDirectory; + } + + public void ensure_package_files_have_compatible_attributes(ChocolateyConfiguration config, IPackage installedPackage, ChocolateyPackageInformation pkgInfo) + { + var installDirectory = get_install_directory(config, installedPackage); + if (!_fileSystem.directory_exists(installDirectory)) return; + _filesService.ensure_compatible_file_attributes(installDirectory, config); } @@ -780,17 +794,7 @@ public void backup_existing_version(ChocolateyConfiguration config, IPackage ins { _fileSystem.create_directory_if_not_exists(ApplicationParameters.PackageBackupLocation); - var pathResolver = NugetCommon.GetPathResolver(config, NugetCommon.GetNuGetFileSystem(config, _nugetLogger)); - var pkgInstallPath = pathResolver.GetInstallPath(installedPackage); - if (!_fileSystem.directory_exists(pkgInstallPath)) - { - var chocoPathResolver = pathResolver as ChocolateyPackagePathResolver; - if (chocoPathResolver != null) - { - chocoPathResolver.UseSideBySidePaths = !chocoPathResolver.UseSideBySidePaths; - pkgInstallPath = chocoPathResolver.GetInstallPath(installedPackage); - } - } + var pkgInstallPath = get_install_directory(config, installedPackage); if (_fileSystem.directory_exists(pkgInstallPath)) { @@ -885,17 +889,7 @@ public void backup_changed_files(string packageInstallPath, ChocolateyConfigurat /// The package information. private void remove_shim_directors(ChocolateyConfiguration config, IPackage installedPackage, ChocolateyPackageInformation pkgInfo) { - var pathResolver = NugetCommon.GetPathResolver(config, NugetCommon.GetNuGetFileSystem(config, _nugetLogger)); - var pkgInstallPath = pathResolver.GetInstallPath(installedPackage); - if (!_fileSystem.directory_exists(pkgInstallPath)) - { - var chocoPathResolver = pathResolver as ChocolateyPackagePathResolver; - if (chocoPathResolver != null) - { - chocoPathResolver.UseSideBySidePaths = !chocoPathResolver.UseSideBySidePaths; - pkgInstallPath = chocoPathResolver.GetInstallPath(installedPackage); - } - } + var pkgInstallPath = get_install_directory(config, installedPackage); if (_fileSystem.directory_exists(pkgInstallPath)) { From d21a1322b188ba3edcf0013ba222f8c42b31b816 Mon Sep 17 00:00:00 2001 From: Richard J Foster Date: Sun, 19 Jul 2015 13:57:26 -0400 Subject: [PATCH 04/14] (GH-268)(spec) Added "before modify" integration test scenarios. These scenarios verify that chocolateyBeforeModify.ps1 is executed on the correct package version when appropriate. --- .../scenarios/InstallScenarios.cs | 12 ++++++++++++ .../scenarios/UninstallScenarios.cs | 12 ++++++++++++ .../scenarios/UpgradeScenarios.cs | 15 +++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs b/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs index 60f73bb1b4..f23b5ff8f1 100644 --- a/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs @@ -101,6 +101,18 @@ public void should_contain_a_message_that_it_would_have_run_a_powershell_script( expectedMessage.ShouldBeTrue(); } + + [Fact] + public void should_not_contain_a_message_that_it_would_have_run_powershell_modification_script() + { + bool expectedMessage = false; + foreach (var message in MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null()) + { + if (message.Contains("chocolateyBeforeModify.ps1")) expectedMessage = true; + } + + expectedMessage.ShouldBeFalse(); + } } [Concern(typeof(ChocolateyInstallCommand))] diff --git a/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs b/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs index ae7d19b2fb..29652b1414 100644 --- a/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs @@ -103,6 +103,12 @@ public void should_contain_a_message_that_it_would_have_run_a_powershell_script( expectedMessage.ShouldBeTrue(); } + + [Fact] + public void should_contain_a_message_that_it_would_have_run_powershell_modification_script() + { + MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.Contains("chocolateyBeforeModify.ps1")).ShouldBeTrue(); + } } [Concern(typeof (ChocolateyUninstallCommand))] @@ -220,6 +226,12 @@ public void config_should_match_package_result_name() packageResult.Name.ShouldEqual(Configuration.PackageNames); } + [Fact] + public void should_have_executed_chocolateyBeforeModify_script() + { + MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.Contains("installpackage 1.0.0 Before Modification")).ShouldBeTrue(); + } + [Fact] public void should_have_executed_chocolateyUninstall_script() { diff --git a/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs b/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs index 15f455aaf0..2ba4db10fe 100644 --- a/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs @@ -303,6 +303,21 @@ public void should_match_the_upgrade_version_of_one_dot_one_dot_zero() _packageResult.Version.ShouldEqual("1.1.0"); } + [Fact] + public void should_have_executed_chocolateyBeforeModify_script_for_original_package() + { + MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.Contains("upgradepackage 1.0.0 Before Modification")).ShouldBeTrue(); + } + + [Fact] + public void should_have_executed_chocolateyBeforeModify_before_chocolateyInstall() + { + MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null() + .SkipWhile(p => !p.Contains("upgradepackage 1.0.0 Before Modification")) + .Any(p => p.EndsWith("upgradepackage 1.1.0 Installed")) + .ShouldBeTrue(); + } + [Fact] public void should_not_have_executed_chocolateyUninstall_script_for_original_package() { From c5e450f45cdc9913a37a1439d81ca90ced71817f Mon Sep 17 00:00:00 2001 From: Richard J Foster Date: Tue, 12 Jan 2016 08:15:08 -0500 Subject: [PATCH 05/14] (GH-268) Add a before_modify action to the PowershellService This action will trigger the execution of chocolateyBeforeModify.ps1 if that script is present in the package. --- .../services/IPowershellService.cs | 14 ++++++ .../services/PowershellService.cs | 45 +++++++++++++------ 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/chocolatey/infrastructure.app/services/IPowershellService.cs b/src/chocolatey/infrastructure.app/services/IPowershellService.cs index 2226f245a9..be9c30cafd 100644 --- a/src/chocolatey/infrastructure.app/services/IPowershellService.cs +++ b/src/chocolatey/infrastructure.app/services/IPowershellService.cs @@ -47,5 +47,19 @@ public interface IPowershellService /// The package result. /// true if the chocolateyUninstall.ps1 was found, even if it has failures bool uninstall(ChocolateyConfiguration configuration, PackageResult packageResult); + + /// + /// Noops the specified package before modify operation. + /// + /// The package result. + void before_modify_noop(PackageResult packageResult); + + /// + /// Runs any before modification script on the specified package. + /// + /// The configuration + /// The package result. + /// true if the chocolateyBeforeModify.ps1 was found, even if it has failures + bool before_modify(ChocolateyConfiguration configuration, PackageResult packageResult); } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/services/PowershellService.cs b/src/chocolatey/infrastructure.app/services/PowershellService.cs index 80308c7a53..0bbaf8a92c 100644 --- a/src/chocolatey/infrastructure.app/services/PowershellService.cs +++ b/src/chocolatey/infrastructure.app/services/PowershellService.cs @@ -16,6 +16,7 @@ namespace chocolatey.infrastructure.app.services { using System; + using System.Collections.Generic; using System.IO; using System.Linq; using System.Management.Automation; @@ -59,7 +60,7 @@ public PowershellService(IFileSystem fileSystem, CustomString customImports) _customImports = customImports; } - public void noop_action(PackageResult packageResult, CommandNameType command) + private string get_script_for_action(PackageResult packageResult, CommandNameType command) { var file = "chocolateyInstall.ps1"; switch (command) @@ -67,14 +68,22 @@ public void noop_action(PackageResult packageResult, CommandNameType command) case CommandNameType.uninstall: file = "chocolateyUninstall.ps1"; break; + + case CommandNameType.upgrade: + file = "chocolateyBeforeModify.ps1"; + break; } var packageDirectory = packageResult.InstallLocation; - var installScript = _fileSystem.get_files(packageDirectory, file, SearchOption.AllDirectories).Where(p => !p.to_lower().contains("\\templates\\")); - if (installScript.Count() != 0) - { - var chocoInstall = installScript.FirstOrDefault(); + var installScript = _fileSystem.get_files(packageDirectory, file, SearchOption.AllDirectories).FirstOrDefault(); + return installScript; + } + public void noop_action(PackageResult packageResult, CommandNameType command) + { + var chocoInstall = get_script_for_action(packageResult, command); + if (!string.IsNullOrEmpty(chocoInstall)) + { this.Log().Info("Would have run '{0}':".format_with(chocoInstall)); this.Log().Warn(_fileSystem.read_file(chocoInstall).escape_curly_braces()); } @@ -100,6 +109,16 @@ public bool uninstall(ChocolateyConfiguration configuration, PackageResult packa return run_action(configuration, packageResult, CommandNameType.uninstall); } + public void before_modify_noop(PackageResult packageResult) + { + noop_action(packageResult, CommandNameType.upgrade); + } + + public bool before_modify(ChocolateyConfiguration configuration, PackageResult packageResult) + { + return run_action(configuration, packageResult, CommandNameType.upgrade); + } + private string get_helpers_folder() { return _fileSystem.combine_paths(ApplicationParameters.InstallLocation, "helpers"); @@ -107,8 +126,10 @@ private string get_helpers_folder() public string wrap_script_with_module(string script, ChocolateyConfiguration config) { - var installerModule = _fileSystem.combine_paths(get_helpers_folder(), "chocolateyInstaller.psm1"); - var scriptRunner = _fileSystem.combine_paths(get_helpers_folder(), "chocolateyScriptRunner.ps1"); + var installerModules = _fileSystem.get_files(ApplicationParameters.InstallLocation, "chocolateyInstaller.psm1", SearchOption.AllDirectories); + var installerModule = installerModules.FirstOrDefault(); + var scriptRunners = _fileSystem.get_files(ApplicationParameters.InstallLocation, "chocolateyScriptRunner.ps1", SearchOption.AllDirectories); + var scriptRunner = scriptRunners.FirstOrDefault(); // removed setting all errors to terminating. Will cause too // many issues in existing packages, including upgrading // Chocolatey from older POSH client due to log errors @@ -169,11 +190,9 @@ public bool run_action(ChocolateyConfiguration configuration, PackageResult pack return installerRun; } - var powershellScript = _fileSystem.get_files(packageDirectory, file, SearchOption.AllDirectories).Where(p => !p.to_lower().contains("\\templates\\")); - if (powershellScript.Count() != 0) + var chocoPowerShellScript = get_script_for_action(packageResult, command); + if (!string.IsNullOrEmpty(chocoPowerShellScript)) { - var chocoPowerShellScript = powershellScript.FirstOrDefault(); - var failure = false; //todo: this is here for any possible compatibility issues. Should be reviewed and removed. @@ -260,7 +279,7 @@ public bool run_action(ChocolateyConfiguration configuration, PackageResult pack if (selection.is_equal_to("no")) { Environment.ExitCode = 1; - packageResult.Messages.Add(new ResultMessage(ResultType.Error, "User cancelled powershell portion of installation for '{0}'.{1} Specify -n to skip automated script actions.".format_with(powershellScript.FirstOrDefault(), Environment.NewLine))); + packageResult.Messages.Add(new ResultMessage(ResultType.Error, "User cancelled powershell portion of installation for '{0}'.{1} Specify -n to skip automated script actions.".format_with(chocoPowerShellScript, Environment.NewLine))); } } @@ -316,7 +335,7 @@ public bool run_action(ChocolateyConfiguration configuration, PackageResult pack if (failure) { Environment.ExitCode = result.ExitCode; - packageResult.Messages.Add(new ResultMessage(ResultType.Error, "Error while running '{0}'.{1} See log for details.".format_with(powershellScript.FirstOrDefault(), Environment.NewLine))); + packageResult.Messages.Add(new ResultMessage(ResultType.Error, "Error while running '{0}'.{1} See log for details.".format_with(chocoPowerShellScript, Environment.NewLine))); } packageResult.Messages.Add(new ResultMessage(ResultType.Note, "Ran '{0}'".format_with(chocoPowerShellScript))); } From 4ad1c56508f24c9f395c2e75f1b86a1992f0867b Mon Sep 17 00:00:00 2001 From: Richard J Foster Date: Wed, 9 Dec 2015 08:31:21 -0500 Subject: [PATCH 06/14] (GH-268) Add optional beforeUpgradeAction to upgrade_run method. If not null, this action should be triggered in an update scenario but in the forseeable future the action will only be used by the NugetService (from where it will be used to trigger execution of the chocolateyBeforeModify script described in GH-268). --- src/chocolatey/infrastructure.app/services/CygwinService.cs | 2 +- src/chocolatey/infrastructure.app/services/ISourceRunner.cs | 5 +++-- src/chocolatey/infrastructure.app/services/NugetService.cs | 6 +++--- src/chocolatey/infrastructure.app/services/PythonService.cs | 2 +- .../infrastructure.app/services/RubyGemsService.cs | 2 +- src/chocolatey/infrastructure.app/services/WebPiService.cs | 2 +- .../infrastructure.app/services/WindowsFeatureService.cs | 2 +- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/chocolatey/infrastructure.app/services/CygwinService.cs b/src/chocolatey/infrastructure.app/services/CygwinService.cs index 0019f572a5..02b48531a4 100644 --- a/src/chocolatey/infrastructure.app/services/CygwinService.cs +++ b/src/chocolatey/infrastructure.app/services/CygwinService.cs @@ -263,7 +263,7 @@ public ConcurrentDictionary upgrade_noop(ChocolateyConfig return new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase); } - public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction) + public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction, Action beforeUpgradeAction) { throw new NotImplementedException("{0} does not implement upgrade".format_with(APP_NAME)); } diff --git a/src/chocolatey/infrastructure.app/services/ISourceRunner.cs b/src/chocolatey/infrastructure.app/services/ISourceRunner.cs index c881f10a64..b8aaaa271b 100644 --- a/src/chocolatey/infrastructure.app/services/ISourceRunner.cs +++ b/src/chocolatey/infrastructure.app/services/ISourceRunner.cs @@ -80,14 +80,15 @@ public interface ISourceRunner /// The configuration. /// The action to continue with for each noop test upgrade. ConcurrentDictionary upgrade_noop(ChocolateyConfiguration config, Action continueAction); - + /// /// Upgrades packages from NuGet related feeds /// /// The configuration. /// The action to continue with when upgrade is successful. + /// The action (if any) to run on any currently installed package before triggering the upgrade. /// results of installs - ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction); + ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction, Action beforeUpgradeAction = null); /// /// Run uninstall in noop mode diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 4e464bbb5e..e828b806a2 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -500,12 +500,12 @@ public ConcurrentDictionary upgrade_noop(ChocolateyConfig return upgrade_run(config, continueAction, performAction: false); } - public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction) + public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction, Action beforeUpgradeAction = null) { - return upgrade_run(config, continueAction, performAction: true); + return upgrade_run(config, continueAction, performAction: true, beforeUpgradeAction: beforeUpgradeAction); } - public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction, bool performAction) + public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction, bool performAction, Action beforeUpgradeAction = null) { _fileSystem.create_directory_if_not_exists(ApplicationParameters.PackagesLocation); var packageInstalls = new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase); diff --git a/src/chocolatey/infrastructure.app/services/PythonService.cs b/src/chocolatey/infrastructure.app/services/PythonService.cs index ad138cd6da..ef4a562c33 100644 --- a/src/chocolatey/infrastructure.app/services/PythonService.cs +++ b/src/chocolatey/infrastructure.app/services/PythonService.cs @@ -392,7 +392,7 @@ public ConcurrentDictionary upgrade_noop(ChocolateyConfig return new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase); } - public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction) + public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction, Action beforeUpgradeAction) { set_executable_path_if_not_set(); var args = build_args(config, _upgradeArguments); diff --git a/src/chocolatey/infrastructure.app/services/RubyGemsService.cs b/src/chocolatey/infrastructure.app/services/RubyGemsService.cs index 7190285e8b..6e67470842 100644 --- a/src/chocolatey/infrastructure.app/services/RubyGemsService.cs +++ b/src/chocolatey/infrastructure.app/services/RubyGemsService.cs @@ -246,7 +246,7 @@ public ConcurrentDictionary upgrade_noop(ChocolateyConfig return new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase); } - public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction) + public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction, Action beforeUpgradeAction) { throw new NotImplementedException("{0} does not implement upgrade".format_with(APP_NAME)); } diff --git a/src/chocolatey/infrastructure.app/services/WebPiService.cs b/src/chocolatey/infrastructure.app/services/WebPiService.cs index d58e78bef8..3a0e580833 100644 --- a/src/chocolatey/infrastructure.app/services/WebPiService.cs +++ b/src/chocolatey/infrastructure.app/services/WebPiService.cs @@ -254,7 +254,7 @@ public ConcurrentDictionary upgrade_noop(ChocolateyConfig return new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase); } - public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction) + public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction, Action beforeUpgradeAction) { throw new NotImplementedException("{0} does not implement upgrade".format_with(APP_NAME)); } diff --git a/src/chocolatey/infrastructure.app/services/WindowsFeatureService.cs b/src/chocolatey/infrastructure.app/services/WindowsFeatureService.cs index ae9ee3c972..ce5e4187da 100644 --- a/src/chocolatey/infrastructure.app/services/WindowsFeatureService.cs +++ b/src/chocolatey/infrastructure.app/services/WindowsFeatureService.cs @@ -324,7 +324,7 @@ public ConcurrentDictionary upgrade_noop(ChocolateyConfig return new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase); } - public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction) + public ConcurrentDictionary upgrade_run(ChocolateyConfiguration config, Action continueAction, Action beforeUpgradeAction) { set_executable_path_if_not_set(); throw new NotImplementedException("{0} does not implement upgrade".format_with(APP_NAME)); From 0a1434c9679f2739eae1f19f622f61eed67e4c74 Mon Sep 17 00:00:00 2001 From: Richard J Foster Date: Thu, 10 Dec 2015 08:26:45 -0500 Subject: [PATCH 07/14] (GH-268) Add before-package-upgrade method to ChocolateyPackageService This method is passed into the ISourceRunner instance's upgrade_run as the beforeUpgradeAction. Only the NugetService currently uses it to trigger execution of the pre-modification script. --- .../services/ChocolateyPackageService.cs | 20 +++++++++++++++++-- .../services/PowershellService.cs | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs index 978b5269dc..4422212ec1 100644 --- a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs +++ b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs @@ -551,7 +551,9 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu get_environment_before(config, allowLogging: true); - var packageUpgrades = perform_source_runner_function(config, r => r.upgrade_run(config, action)); + var beforeUpgradeAction = new Action( packageResult => before_package_upgrade(packageResult, config)); + + var packageUpgrades = perform_source_runner_function(config, r => r.upgrade_run(config, action, beforeUpgradeAction)); var upgradeFailures = packageUpgrades.Count(p => !p.Value.Success); var upgradeWarnings = packageUpgrades.Count(p => p.Value.Warning); @@ -591,12 +593,21 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu return packageUpgrades; } + private void before_package_upgrade(PackageResult packageResult, ChocolateyConfiguration config) + { + _powershellService.before_modify(config, packageResult); + } + public void uninstall_noop(ChocolateyConfiguration config) { Action action = null; if (config.SourceType == SourceType.normal) { - action = (pkg) => _powershellService.uninstall_noop(pkg); + action = (pkg) => + { + _powershellService.before_modify_noop(pkg); + _powershellService.uninstall_noop(pkg); + }; } perform_source_runner_action(config, r => r.uninstall_noop(config, action)); @@ -660,6 +671,11 @@ public void handle_package_uninstall(PackageResult packageResult, ChocolateyConf packageResult.InstallLocation += ".{0}".format_with(packageResult.Package.Version.to_string()); } + if (!config.SkipPackageInstallProvider) + { + _powershellService.before_modify(config, packageResult); + } + _shimgenService.uninstall(config, packageResult); if (!config.SkipPackageInstallProvider) diff --git a/src/chocolatey/infrastructure.app/services/PowershellService.cs b/src/chocolatey/infrastructure.app/services/PowershellService.cs index 0bbaf8a92c..74b1f3953f 100644 --- a/src/chocolatey/infrastructure.app/services/PowershellService.cs +++ b/src/chocolatey/infrastructure.app/services/PowershellService.cs @@ -84,7 +84,7 @@ public void noop_action(PackageResult packageResult, CommandNameType command) var chocoInstall = get_script_for_action(packageResult, command); if (!string.IsNullOrEmpty(chocoInstall)) { - this.Log().Info("Would have run '{0}':".format_with(chocoInstall)); + this.Log().Info("Would have run '{0}':".format_with(_fileSystem.get_file_name(chocoInstall))); this.Log().Warn(_fileSystem.read_file(chocoInstall).escape_curly_braces()); } } From 393fb104cef8b269416dd520b2328787e2c9229c Mon Sep 17 00:00:00 2001 From: Richard J Foster Date: Fri, 8 Jan 2016 20:29:49 -0500 Subject: [PATCH 08/14] (GH-268) Trigger beforeUpgradeAction from the NugetService. --- src/chocolatey/infrastructure.app/services/NugetService.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index e828b806a2..0a6a9c1773 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -709,6 +709,11 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu version == null ? null : version.ToString())) { ensure_package_files_have_compatible_attributes(config, installedPackage, pkgInfo); + if (beforeUpgradeAction != null) + { + var currentPackageResult = new PackageResult(installedPackage, get_install_directory(config, installedPackage)); + beforeUpgradeAction(currentPackageResult); + } rename_legacy_package_version(config, installedPackage, pkgInfo); backup_existing_version(config, installedPackage, pkgInfo); remove_shim_directors(config, installedPackage, pkgInfo); From 8522c67ee2496eec45a26081f9b8da2149fe8a69 Mon Sep 17 00:00:00 2001 From: Richard J Foster Date: Sat, 9 Jan 2016 08:51:21 -0500 Subject: [PATCH 09/14] (GH-268) Use MockLogger.contains_message in verification expressions. --- .../scenarios/InstallScenarios.cs | 18 +++--------------- .../scenarios/UninstallScenarios.cs | 14 ++++---------- .../scenarios/UpgradeScenarios.cs | 12 +++++++++--- 3 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs b/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs index f23b5ff8f1..e7d9e732fc 100644 --- a/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs @@ -93,25 +93,13 @@ public void should_contain_a_message_that_it_would_have_used_Nuget_to_install_a_ [Fact] public void should_contain_a_message_that_it_would_have_run_a_powershell_script() { - bool expectedMessage = false; - foreach (var message in MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null()) - { - if (message.Contains("chocolateyinstall.ps1")) expectedMessage = true; - } - - expectedMessage.ShouldBeTrue(); + MockLogger.contains_message("chocolateyinstall.ps1", LogLevel.Info).ShouldBeTrue(); } [Fact] public void should_not_contain_a_message_that_it_would_have_run_powershell_modification_script() { - bool expectedMessage = false; - foreach (var message in MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null()) - { - if (message.Contains("chocolateyBeforeModify.ps1")) expectedMessage = true; - } - - expectedMessage.ShouldBeFalse(); + MockLogger.contains_message("chocolateyBeforeModify.ps1", LogLevel.Info).ShouldBeFalse(); } } @@ -331,7 +319,7 @@ public void should_have_a_version_of_one_dot_zero_dot_zero() [Fact] public void should_have_executed_chocolateyInstall_script() { - MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.Contains("installpackage v1.0.0 has been installed")).ShouldBeTrue("Installpackage info message not seen. Info messages that were seen: {0}".format_with(string.Join(Environment.NewLine, MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null()))); + MockLogger.contains_message("installpackage v1.0.0 has been installed", LogLevel.Info).ShouldBeTrue(); } } diff --git a/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs b/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs index 29652b1414..59fb2094c2 100644 --- a/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/UninstallScenarios.cs @@ -95,19 +95,13 @@ public void should_contain_a_message_that_it_would_have_uninstalled_a_package() [Fact] public void should_contain_a_message_that_it_would_have_run_a_powershell_script() { - bool expectedMessage = false; - foreach (var message in MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null()) - { - if (message.Contains("chocolateyuninstall.ps1")) expectedMessage = true; - } - - expectedMessage.ShouldBeTrue(); + MockLogger.contains_message("chocolateyuninstall.ps1").ShouldBeTrue(); } [Fact] public void should_contain_a_message_that_it_would_have_run_powershell_modification_script() { - MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.Contains("chocolateyBeforeModify.ps1")).ShouldBeTrue(); + MockLogger.contains_message("chocolateyBeforeModify.ps1").ShouldBeTrue(); } } @@ -229,13 +223,13 @@ public void config_should_match_package_result_name() [Fact] public void should_have_executed_chocolateyBeforeModify_script() { - MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.Contains("installpackage 1.0.0 Before Modification")).ShouldBeTrue(); + MockLogger.contains_message("installpackage 1.0.0 Before Modification", LogLevel.Info).ShouldBeTrue(); } [Fact] public void should_have_executed_chocolateyUninstall_script() { - MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.EndsWith("installpackage 1.0.0 Uninstalled")).ShouldBeTrue(); + MockLogger.contains_message("installpackage 1.0.0 Uninstalled", LogLevel.Info).ShouldBeTrue(); } } diff --git a/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs b/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs index 2ba4db10fe..9d5dbf2e71 100644 --- a/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs @@ -306,7 +306,7 @@ public void should_match_the_upgrade_version_of_one_dot_one_dot_zero() [Fact] public void should_have_executed_chocolateyBeforeModify_script_for_original_package() { - MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.Contains("upgradepackage 1.0.0 Before Modification")).ShouldBeTrue(); + MockLogger.contains_message("upgradepackage 1.0.0 Before Modification", LogLevel.Info).ShouldBeTrue(); } [Fact] @@ -321,13 +321,19 @@ public void should_have_executed_chocolateyBeforeModify_before_chocolateyInstall [Fact] public void should_not_have_executed_chocolateyUninstall_script_for_original_package() { - MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.EndsWith("upgradepackage 1.0.0 Uninstalled")).ShouldBeFalse(); + MockLogger.contains_message("upgradepackage 1.0.0 Uninstalled", LogLevel.Info).ShouldBeFalse(); + } + + [Fact] + public void should_not_have_executed_chocolateyBeforeModify_script_for_new_package() + { + MockLogger.contains_message("upgradepackage 1.1.0 Before Modification", LogLevel.Info).ShouldBeFalse(); } [Fact] public void should_have_executed_chocolateyInstall_script_for_new_package() { - MockLogger.MessagesFor(LogLevel.Info).or_empty_list_if_null().Any(p => p.EndsWith("upgradepackage 1.1.0 Installed")).ShouldBeTrue(); + MockLogger.contains_message("upgradepackage 1.1.0 Installed", LogLevel.Info).ShouldBeTrue(); } } From a7d92f53263acf6205965b65bfafa4282563a8cf Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Sat, 9 Apr 2016 13:28:11 -0500 Subject: [PATCH 10/14] (maint) formatting --- .../infrastructure.app/services/ChocolateyPackageService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs index 4422212ec1..b89cb47477 100644 --- a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs +++ b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs @@ -551,7 +551,7 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu get_environment_before(config, allowLogging: true); - var beforeUpgradeAction = new Action( packageResult => before_package_upgrade(packageResult, config)); + var beforeUpgradeAction = new Action(packageResult => before_package_upgrade(packageResult, config)); var packageUpgrades = perform_source_runner_function(config, r => r.upgrade_run(config, action, beforeUpgradeAction)); From 43c6d109ed592220dcaf278b7f068a26f9c503a3 Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Sat, 9 Apr 2016 13:29:07 -0500 Subject: [PATCH 11/14] (GH-268) Rename Legacy Prior to Before Modify Ensure the folder is renamed prior to running before modify for the package. --- src/chocolatey/infrastructure.app/services/NugetService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 0a6a9c1773..6a722e2a11 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -709,12 +709,13 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu version == null ? null : version.ToString())) { ensure_package_files_have_compatible_attributes(config, installedPackage, pkgInfo); + rename_legacy_package_version(config, installedPackage, pkgInfo); if (beforeUpgradeAction != null) { var currentPackageResult = new PackageResult(installedPackage, get_install_directory(config, installedPackage)); beforeUpgradeAction(currentPackageResult); } - rename_legacy_package_version(config, installedPackage, pkgInfo); + backup_existing_version(config, installedPackage, pkgInfo); remove_shim_directors(config, installedPackage, pkgInfo); if (config.Force && (installedPackage.Version == availablePackage.Version)) From 4a9bc7312f8d24731f14a178977cce4900330046 Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Sat, 9 Apr 2016 13:33:55 -0500 Subject: [PATCH 12/14] (GH-268) Revert removed fixes - Adding back in GH-560 - loading modules from known location (90d53ee) - Adding back in GH-542 - not running templated scripts (d5f09bf) --- .../services/PowershellService.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/chocolatey/infrastructure.app/services/PowershellService.cs b/src/chocolatey/infrastructure.app/services/PowershellService.cs index 74b1f3953f..53396a1f28 100644 --- a/src/chocolatey/infrastructure.app/services/PowershellService.cs +++ b/src/chocolatey/infrastructure.app/services/PowershellService.cs @@ -75,8 +75,13 @@ private string get_script_for_action(PackageResult packageResult, CommandNameTyp } var packageDirectory = packageResult.InstallLocation; - var installScript = _fileSystem.get_files(packageDirectory, file, SearchOption.AllDirectories).FirstOrDefault(); - return installScript; + var installScript = _fileSystem.get_files(packageDirectory, file, SearchOption.AllDirectories).Where(p => !p.to_lower().contains("\\templates\\")); + if (installScript.Count() != 0) + { + return installScript.FirstOrDefault(); + } + + return string.Empty; } public void noop_action(PackageResult packageResult, CommandNameType command) @@ -126,10 +131,9 @@ private string get_helpers_folder() public string wrap_script_with_module(string script, ChocolateyConfiguration config) { - var installerModules = _fileSystem.get_files(ApplicationParameters.InstallLocation, "chocolateyInstaller.psm1", SearchOption.AllDirectories); - var installerModule = installerModules.FirstOrDefault(); - var scriptRunners = _fileSystem.get_files(ApplicationParameters.InstallLocation, "chocolateyScriptRunner.ps1", SearchOption.AllDirectories); - var scriptRunner = scriptRunners.FirstOrDefault(); + var installerModule = _fileSystem.combine_paths(get_helpers_folder(), "chocolateyInstaller.psm1"); + var scriptRunner = _fileSystem.combine_paths(get_helpers_folder(), "chocolateyScriptRunner.ps1"); + // removed setting all errors to terminating. Will cause too // many issues in existing packages, including upgrading // Chocolatey from older POSH client due to log errors From da5dce9830398826bd2335c5e15a700bb1774854 Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Sat, 9 Apr 2016 13:45:01 -0500 Subject: [PATCH 13/14] (maint) remove comment --- src/chocolatey/infrastructure.app/services/PowershellService.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chocolatey/infrastructure.app/services/PowershellService.cs b/src/chocolatey/infrastructure.app/services/PowershellService.cs index 53396a1f28..266fa62c0c 100644 --- a/src/chocolatey/infrastructure.app/services/PowershellService.cs +++ b/src/chocolatey/infrastructure.app/services/PowershellService.cs @@ -199,7 +199,6 @@ public bool run_action(ChocolateyConfiguration configuration, PackageResult pack { var failure = false; - //todo: this is here for any possible compatibility issues. Should be reviewed and removed. ConfigurationBuilder.set_environment_variables(configuration); var package = packageResult.Package; From 9b165e94e270b93947282500669cf629adf71ee8 Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Sat, 9 Apr 2016 13:46:36 -0500 Subject: [PATCH 14/14] (GH-268)(specs) BeforeModify failure is ignored A failure in the before modify script should report the error but not do anything to stop the script from failing. --- .../upgradepackage/1.0.0/tools/chocolateyBeforeModify.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/chocolatey.tests.integration/context/upgradepackage/1.0.0/tools/chocolateyBeforeModify.ps1 b/src/chocolatey.tests.integration/context/upgradepackage/1.0.0/tools/chocolateyBeforeModify.ps1 index af5bb142e8..45014bb0b3 100644 --- a/src/chocolatey.tests.integration/context/upgradepackage/1.0.0/tools/chocolateyBeforeModify.ps1 +++ b/src/chocolatey.tests.integration/context/upgradepackage/1.0.0/tools/chocolateyBeforeModify.ps1 @@ -1 +1,3 @@ -Write-Output "$env:PackageName $env:PackageVersion Before Modification" \ No newline at end of file +Write-Output "$env:PackageName $env:PackageVersion Before Modification" + +throw "This should not break the upgrade/uninstall" \ No newline at end of file