diff --git a/.uppercut b/.uppercut
index fee3affcda..cb75e8b2c1 100644
--- a/.uppercut
+++ b/.uppercut
@@ -17,10 +17,10 @@
-
+
-
-
+
+
diff --git a/src/chocolatey.tests/infrastructure.app/services/NugetServiceSpecs.cs b/src/chocolatey.tests/infrastructure.app/services/NugetServiceSpecs.cs
index 4d8e20b933..7e17230cf0 100644
--- a/src/chocolatey.tests/infrastructure.app/services/NugetServiceSpecs.cs
+++ b/src/chocolatey.tests/infrastructure.app/services/NugetServiceSpecs.cs
@@ -206,6 +206,7 @@ public void should_remove_an_unchanged_file()
};
fileSystem.Setup(x => x.get_files(It.IsAny(), It.IsAny(), SearchOption.AllDirectories)).Returns(fileSystemFiles);
filesService.Setup(x => x.get_package_file(It.IsAny())).Returns(packageFile);
+ fileSystem.Setup(x => x.file_exists(filePath)).Returns(true);
because();
@@ -236,6 +237,7 @@ public void should_not_delete_a_changed_file()
};
fileSystem.Setup(x => x.get_files(It.IsAny(), It.IsAny(), SearchOption.AllDirectories)).Returns(fileSystemFiles);
filesService.Setup(x => x.get_package_file(It.IsAny())).Returns(packageFileWithUpdatedChecksum);
+ fileSystem.Setup(x => x.file_exists(filePath)).Returns(true);
because();
@@ -267,8 +269,8 @@ public void should_not_delete_an_unfound_file()
};
fileSystem.Setup(x => x.get_files(It.IsAny(), It.IsAny(), SearchOption.AllDirectories)).Returns(fileSystemFiles);
-
filesService.Setup(x => x.get_package_file(It.IsAny())).Returns(packageFileNotInOriginal);
+ fileSystem.Setup(x => x.file_exists(filePath)).Returns(false);
because();
diff --git a/src/chocolatey/GetChocolatey.cs b/src/chocolatey/GetChocolatey.cs
index c4f0657d46..fc9e929d4b 100644
--- a/src/chocolatey/GetChocolatey.cs
+++ b/src/chocolatey/GetChocolatey.cs
@@ -29,6 +29,7 @@ namespace chocolatey
using infrastructure.extractors;
using infrastructure.logging;
using infrastructure.registration;
+ using infrastructure.synchronization;
using resources;
using Assembly = infrastructure.adapters.Assembly;
using IFileSystem = infrastructure.filesystem.IFileSystem;
@@ -40,12 +41,20 @@ namespace chocolatey
///
public static class Lets
{
- public static GetChocolatey GetChocolatey()
+ private static readonly GetChocolatey _chocolatey = GlobalMutex.enter(() => set_up(), 5);
+
+ private static GetChocolatey set_up()
{
add_assembly_resolver();
+
return new GetChocolatey();
}
+ public static GetChocolatey GetChocolatey()
+ {
+ return _chocolatey;
+ }
+
private static ResolveEventHandler _handler = null;
private static void add_assembly_resolver()
diff --git a/src/chocolatey/infrastructure.app/ApplicationParameters.cs b/src/chocolatey/infrastructure.app/ApplicationParameters.cs
index d4330537cb..a466bfcbf5 100644
--- a/src/chocolatey/infrastructure.app/ApplicationParameters.cs
+++ b/src/chocolatey/infrastructure.app/ApplicationParameters.cs
@@ -166,6 +166,8 @@ public static class Features
public static readonly string ShowDownloadProgress = "showDownloadProgress";
public static readonly string StopOnFirstPackageFailure = "stopOnFirstPackageFailure";
public static readonly string UseRememberedArgumentsForUpgrades = "useRememberedArgumentsForUpgrades";
+ public static readonly string IgnoreUnfoundPackagesOnUpgradeOutdated = "ignoreUnfoundPackagesOnUpgradeOutdated";
+ public static readonly string RemovePackageInformationOnUninstall = "removePackageInformationOnUninstall";
}
public static class Messages
diff --git a/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs b/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs
index 6ec9a7d20c..353b71fb90 100644
--- a/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs
+++ b/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs
@@ -284,8 +284,10 @@ private static void set_feature_flags(ChocolateyConfiguration config, ConfigFile
config.Features.UseFipsCompliantChecksums = set_feature_flag(ApplicationParameters.Features.UseFipsCompliantChecksums, configFileSettings, defaultEnabled: false, description: "Use FIPS Compliant Checksums - Ensure checksumming done by choco uses FIPS compliant algorithms. Not recommended unless required by FIPS Mode. Enabling on an existing installation could have unintended consequences related to upgrades/uninstalls. Available in 0.9.10+.");
config.Features.ShowNonElevatedWarnings = set_feature_flag(ApplicationParameters.Features.ShowNonElevatedWarnings, configFileSettings, defaultEnabled: true, description: "Show Non-Elevated Warnings - Display non-elevated warnings. Available in 0.10.4+.");
config.Features.ShowDownloadProgress = set_feature_flag(ApplicationParameters.Features.ShowDownloadProgress, configFileSettings, defaultEnabled: true, description: "Show Download Progress - Show download progress percentages in the CLI. Available in 0.10.4+.");
- config.Features.StopOnFirstPackageFailure = set_feature_flag(ApplicationParameters.Features.StopOnFirstPackageFailure, configFileSettings, defaultEnabled: false, description: "Stop On First Package Failure - stop running install, upgrade or uninstall on first package failure instead of continuing with others. As this will affect upgrade all, it is normally recommended to leave this off. Available in 0.10.4+.");
- config.Features.UseRememberedArgumentsForUpgrades = set_feature_flag(ApplicationParameters.Features.UseRememberedArgumentsForUpgrades, configFileSettings, defaultEnabled: false, description: "Use Remembered Arguments For Upgrades - when running upgrades, use arguments for upgrade that were used for installation ('remembered'). This is helpful when running upgrade for all packages. Available in 0.10.4+. This is considered in preview for 0.10.4 and will be flipped to on by default in a future release.");
+ config.Features.StopOnFirstPackageFailure = set_feature_flag(ApplicationParameters.Features.StopOnFirstPackageFailure, configFileSettings, defaultEnabled: false, description: "Stop On First Package Failure - Stop running install, upgrade or uninstall on first package failure instead of continuing with others. As this will affect upgrade all, it is normally recommended to leave this off. Available in 0.10.4+.");
+ config.Features.UseRememberedArgumentsForUpgrades = set_feature_flag(ApplicationParameters.Features.UseRememberedArgumentsForUpgrades, configFileSettings, defaultEnabled: false, description: "Use Remembered Arguments For Upgrades - When running upgrades, use arguments for upgrade that were used for installation ('remembered'). This is helpful when running upgrade for all packages. Available in 0.10.4+. This is considered in preview for 0.10.4 and will be flipped to on by default in a future release.");
+ config.Features.IgnoreUnfoundPackagesOnUpgradeOutdated = set_feature_flag(ApplicationParameters.Features.IgnoreUnfoundPackagesOnUpgradeOutdated, configFileSettings, defaultEnabled: false, description: "Ignore Unfound Packages On Upgrade Outdated - When checking outdated or upgrades, if a package is not found against sources specified, don't report the package at all. Available in 0.10.9+.");
+ config.Features.RemovePackageInformationOnUninstall = set_feature_flag(ApplicationParameters.Features.RemovePackageInformationOnUninstall, configFileSettings, defaultEnabled: false, description: "Remove Stored Package Information On Uninstall - When a package is uninstalled, should the stored package information also be removed? Available in 0.10.9+.");
config.Features.ScriptsCheckLastExitCode = set_feature_flag(ApplicationParameters.Features.ScriptsCheckLastExitCode, configFileSettings, defaultEnabled: false, description: "Scripts Check $LastExitCode (external commands) - Leave this off unless you absolutely need it while you fix your package scripts to use `throw 'error message'` or `Set-PowerShellExitCode #` instead of `exit #`. This behavior started in 0.9.10 and produced hard to find bugs. If the last external process exits successfully but with an exit code of not zero, this could cause hard to detect package failures. Available in 0.10.3+. Will be removed in 0.11.0.");
config.PromptForConfirmation = !set_feature_flag(ApplicationParameters.Features.AllowGlobalConfirmation, configFileSettings, defaultEnabled: false, description: "Prompt for confirmation in scripts or bypass.");
}
diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyOutdatedCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyOutdatedCommand.cs
index 5329e222d2..12a596ec98 100644
--- a/src/chocolatey/infrastructure.app/commands/ChocolateyOutdatedCommand.cs
+++ b/src/chocolatey/infrastructure.app/commands/ChocolateyOutdatedCommand.cs
@@ -55,6 +55,9 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon
.Add("ignore-pinned",
"Ignore Pinned - Ignore pinned packages. Defaults to false. Available in 0.10.6+.",
option => configuration.OutdatedCommand.IgnorePinned = option != null)
+ .Add("ignore-unfound",
+ "Ignore Unfound Packages - Ignore packages that are not found on the sources used (or the defaults). Overrides the default feature '{0}' set to '{1}'. Available in 0.10.9+.".format_with(ApplicationParameters.Features.IgnoreUnfoundPackagesOnUpgradeOutdated, configuration.Features.IgnoreUnfoundPackagesOnUpgradeOutdated.to_string()),
+ option => configuration.Features.IgnoreUnfoundPackagesOnUpgradeOutdated = option != null)
;
}
diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs
index d1c318580c..c3fd6b4005 100644
--- a/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs
+++ b/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs
@@ -84,8 +84,11 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon
"Skip Powershell - Do not run chocolateyInstall.ps1. Defaults to false.",
option => configuration.SkipPackageInstallProvider = option != null)
.Add("failonunfound|fail-on-unfound",
- "Fail On Unfound Packages - If a package is not found in feeds specified, fail instead of warn.",
+ "Fail On Unfound Packages - If a package is not found in sources specified, fail instead of warn.",
option => configuration.UpgradeCommand.FailOnUnfound = option != null)
+ .Add("ignore-unfound",
+ "Ignore Unfound Packages - Ignore packages that are not found on the sources used (or the defaults). Overrides the default feature '{0}' set to '{1}'. Available in 0.10.9+.".format_with(ApplicationParameters.Features.IgnoreUnfoundPackagesOnUpgradeOutdated, configuration.Features.IgnoreUnfoundPackagesOnUpgradeOutdated.to_string()),
+ option => configuration.Features.IgnoreUnfoundPackagesOnUpgradeOutdated = option != null)
.Add("failonnotinstalled|fail-on-not-installed",
"Fail On Non-installed Packages - If a package is not already installed, fail instead of installing.",
option => configuration.UpgradeCommand.FailOnNotInstalled = option != null)
diff --git a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs
index 2cdd109a4e..1ed54c67ca 100644
--- a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs
+++ b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs
@@ -387,6 +387,8 @@ public sealed class FeaturesConfiguration
public bool ShowDownloadProgress { get; set; }
public bool StopOnFirstPackageFailure { get; set; }
public bool UseRememberedArgumentsForUpgrades { get; set; }
+ public bool IgnoreUnfoundPackagesOnUpgradeOutdated { get; set; }
+ public bool RemovePackageInformationOnUninstall { get; set; }
//todo remove in 0.11.0
public bool ScriptsCheckLastExitCode { get; set; }
diff --git a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs
index f964448891..a6375d27b5 100644
--- a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs
+++ b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs
@@ -925,7 +925,8 @@ public void handle_package_uninstall(PackageResult packageResult, ChocolateyConf
private void uninstall_cleanup(ChocolateyConfiguration config, PackageResult packageResult)
{
- _packageInfoService.remove_package_information(packageResult.Package);
+ if (config.Features.RemovePackageInformationOnUninstall) _packageInfoService.remove_package_information(packageResult.Package);
+
ensure_bad_package_path_is_clean(config, packageResult);
remove_rollback_if_exists(packageResult);
handle_extension_packages(config, packageResult);
diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs
index 063470bf79..c937ea8644 100644
--- a/src/chocolatey/infrastructure.app/services/NugetService.cs
+++ b/src/chocolatey/infrastructure.app/services/NugetService.cs
@@ -667,6 +667,8 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu
if (availablePackage == null)
{
+ if (config.Features.IgnoreUnfoundPackagesOnUpgradeOutdated) continue;
+
string logMessage = "{0} was not found with the source(s) listed.{1} If you specified a particular version and are receiving this message, it is possible that the package name exists but the version does not.{1} Version: \"{2}\"; Source(s): \"{3}\"".format_with(packageName, Environment.NewLine, config.Version, config.Sources);
var unfoundResult = packageInstalls.GetOrAdd(packageName, new PackageResult(packageName, version.to_string(), null));
@@ -1059,8 +1061,11 @@ private void remove_shim_directors(ChocolateyConfiguration config, IPackage inst
private void remove_cache_for_package(ChocolateyConfiguration config, IPackage installedPackage)
{
+ this.Log().Debug(ChocolateyLoggers.Verbose, "Ensuring removal of package cache files.");
var cacheDirectory = _fileSystem.combine_paths(config.CacheLocation, installedPackage.Id, installedPackage.Version.to_string());
+ if (!_fileSystem.directory_exists(cacheDirectory)) return;
+
FaultTolerance.try_catch_with_logging_exception(
() => _fileSystem.delete_directory_if_exists(cacheDirectory, recursive: true),
"Unable to removed cached files");
@@ -1324,7 +1329,7 @@ public ConcurrentDictionary uninstall_run(ChocolateyConfi
rename_legacy_package_version(config, packageVersion, pkgInfo);
remove_rollback_directory_if_exists(packageName);
backup_existing_version(config, packageVersion, pkgInfo);
- packageManager.UninstallPackage(packageVersion.Id, forceRemove: config.Force, removeDependencies: config.ForceDependencies, version: packageVersion.Version);
+ packageManager.UninstallPackage(packageVersion.Id.to_lower(), forceRemove: config.Force, removeDependencies: config.ForceDependencies, version: packageVersion.Version);
ensure_nupkg_is_removed(packageVersion, pkgInfo);
remove_installation_files(packageVersion, pkgInfo);
remove_cache_for_package(config, packageVersion);
@@ -1364,12 +1369,15 @@ public ConcurrentDictionary uninstall_run(ChocolateyConfi
/// The package information.
private void ensure_nupkg_is_removed(IPackage removedPackage, ChocolateyPackageInformation pkgInfo)
{
+ this.Log().Debug(ChocolateyLoggers.Verbose, "Removing nupkg if it still exists.");
var isSideBySide = pkgInfo != null && pkgInfo.IsSideBySide;
var nupkgFile = "{0}{1}.nupkg".format_with(removedPackage.Id, isSideBySide ? "." + removedPackage.Version.to_string() : string.Empty);
var installDir = _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, "{0}{1}".format_with(removedPackage.Id, isSideBySide ? "." + removedPackage.Version.to_string() : string.Empty));
var nupkg = _fileSystem.combine_paths(installDir, nupkgFile);
+ if (!_fileSystem.file_exists(nupkg)) return;
+
FaultTolerance.try_catch_with_logging_exception(
() => _fileSystem.delete_file(nupkg),
"Error deleting nupkg file",
@@ -1378,6 +1386,7 @@ private void ensure_nupkg_is_removed(IPackage removedPackage, ChocolateyPackageI
public void remove_installation_files(IPackage removedPackage, ChocolateyPackageInformation pkgInfo)
{
+ this.Log().Debug(ChocolateyLoggers.Verbose, "Ensuring removal of installation files.");
var isSideBySide = pkgInfo != null && pkgInfo.IsSideBySide;
var installDir = _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, "{0}{1}".format_with(removedPackage.Id, isSideBySide ? "." + removedPackage.Version.to_string() : string.Empty));
@@ -1390,6 +1399,8 @@ public void remove_installation_files(IPackage removedPackage, ChocolateyPackage
if (fileSnapshot.Checksum == _filesService.get_package_file(file).Checksum)
{
+ if (!_fileSystem.file_exists(file)) continue;
+
FaultTolerance.try_catch_with_logging_exception(
() => _fileSystem.delete_file(file),
"Error deleting file");