Skip to content

Commit 85ab916

Browse files
committed
(#2886) Switch remembered args to only change local configuration
This adds a new method, GetPackageConfigFromRememberedArguments which is similar to SetConfigFromRememberedArguments, but operates using a different method. First, a OptionSet is set up, so only the config that is passed in is modified, instead of the config that the global options parser was set with with. Second, it returns the modified configuration instead of the original configuration, because it is the local configuration being modified. Third, it has a more general name and changes log messages to be more general, so it later can more easily be reused for uninstall and export. This change fixes remembered arguments when Chocolatey is used as a library, like in ChocolateyGUI, where the config that is passed to the install_run method is not necessarily the same config object that was used to set up the global argument parser. The downside of using a new commandline parser is that it opens up the possibility of drift between the upgrade/global arguments and this added parser. However, this is not an issue because the format of the saved arguments is known, and any added arguments there would not work without being added here as well, which would be picked up during development.
1 parent 2c37c9a commit 85ab916

File tree

2 files changed

+175
-14
lines changed

2 files changed

+175
-14
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using System.Collections.Concurrent;
1919
using System.Collections.Generic;
2020
using chocolatey.infrastructure.app.configuration;
21+
using chocolatey.infrastructure.app.domain;
2122
using chocolatey.infrastructure.results;
2223

2324
namespace chocolatey.infrastructure.app.services
@@ -67,6 +68,16 @@ public interface INugetService : ISourceRunner
6768
/// <param name="config">The configuration</param>
6869
IEnumerable<PackageResult> GetInstalledPackages(ChocolateyConfiguration config);
6970

71+
72+
/// <summary>
73+
/// Gets the configuration from remembered arguments
74+
/// </summary>
75+
/// <param name="config">The original configuration.</param>
76+
/// <param name="packageInfo">The package information.</param>
77+
/// <returns>The modified configuration, so it can be used</returns>
78+
ChocolateyConfiguration GetPackageConfigFromRememberedArguments(ChocolateyConfiguration config,
79+
ChocolateyPackageInformation packageInfo);
80+
7081
#pragma warning disable IDE0022, IDE1006
7182
[Obsolete("This overload is deprecated and will be removed in v3.")]
7283
ConcurrentDictionary<string, PackageResult> get_outdated(ChocolateyConfiguration config);

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

Lines changed: 164 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,7 @@ public virtual ConcurrentDictionary<string, PackageResult> Upgrade(ChocolateyCon
11161116
continue;
11171117
}
11181118

1119-
SetConfigFromRememberedArguments(config, pkgInfo);
1119+
config = GetPackageConfigFromRememberedArguments(config, pkgInfo);
11201120
var pathResolver = NugetCommon.GetPathResolver(_fileSystem);
11211121
var nugetProject = new FolderNuGetProject(ApplicationParameters.PackagesLocation, pathResolver, NuGetFramework.AnyFramework);
11221122

@@ -1254,12 +1254,12 @@ public virtual ConcurrentDictionary<string, PackageResult> Upgrade(ChocolateyCon
12541254
var logMessage = "{0} is pinned. Skipping pinned package.".FormatWith(packageName);
12551255
packageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage));
12561256
packageResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage));
1257-
1257+
12581258
if (config.RegularOutput)
12591259
{
12601260
this.Log().Warn(ChocolateyLoggers.Important, logMessage);
12611261
}
1262-
1262+
12631263
continue;
12641264
}
12651265
else
@@ -1271,7 +1271,7 @@ public virtual ConcurrentDictionary<string, PackageResult> Upgrade(ChocolateyCon
12711271
{
12721272
this.Log().Warn(ChocolateyLoggers.Important, logMessage);
12731273
}
1274-
1274+
12751275
config.PinPackage = true;
12761276
}
12771277
}
@@ -1344,7 +1344,7 @@ public virtual ConcurrentDictionary<string, PackageResult> Upgrade(ChocolateyCon
13441344
}
13451345

13461346
var removedSources = new HashSet<SourcePackageDependencyInfo>();
1347-
1347+
13481348
if (!config.UpgradeCommand.IgnorePinned)
13491349
{
13501350
RemovePinnedSourceDependencies(sourcePackageDependencyInfos, allLocalPackages);
@@ -1780,12 +1780,7 @@ public virtual ConcurrentDictionary<string, PackageResult> GetOutdated(Chocolate
17801780
return outdatedPackages;
17811781
}
17821782

1783-
/// <summary>
1784-
/// Sets the configuration for the package upgrade
1785-
/// </summary>
1786-
/// <param name="config">The configuration.</param>
1787-
/// <param name="packageInfo">The package information.</param>
1788-
/// <returns>The original unmodified configuration, so it can be reset after upgrade</returns>
1783+
[Obsolete("This method is deprecated and will be removed in v3.")]
17891784
protected virtual ChocolateyConfiguration SetConfigFromRememberedArguments(ChocolateyConfiguration config, ChocolateyPackageInformation packageInfo)
17901785
{
17911786
if (!config.Features.UseRememberedArgumentsForUpgrades || string.IsNullOrWhiteSpace(packageInfo.Arguments))
@@ -1830,16 +1825,16 @@ protected virtual ChocolateyConfiguration SetConfigFromRememberedArguments(Choco
18301825
ConfigurationOptions.OptionSet.Parse(packageArguments);
18311826

18321827
// there may be overrides from the user running upgrade
1833-
if (!string.IsNullOrWhiteSpace(originalConfig.PackageParameters))
1828+
if (!string.IsNullOrWhiteSpace(originalConfig.PackageParameters))
18341829
{
18351830
config.PackageParameters = originalConfig.PackageParameters;
18361831
}
1837-
1832+
18381833
if (!string.IsNullOrWhiteSpace(originalConfig.InstallArguments))
18391834
{
18401835
config.InstallArguments = originalConfig.InstallArguments;
18411836
}
1842-
1837+
18431838
if (!string.IsNullOrWhiteSpace(originalConfig.SourceCommand.Username))
18441839
{
18451840
config.SourceCommand.Username = originalConfig.SourceCommand.Username;
@@ -1873,6 +1868,161 @@ protected virtual ChocolateyConfiguration SetConfigFromRememberedArguments(Choco
18731868
return originalConfig;
18741869
}
18751870

1871+
/// <summary>
1872+
/// Gets the configuration from remembered arguments
1873+
/// </summary>
1874+
/// <param name="config">The original configuration.</param>
1875+
/// <param name="packageInfo">The package information.</param>
1876+
/// <returns>The modified configuration, so it can be used</returns>
1877+
public virtual ChocolateyConfiguration GetPackageConfigFromRememberedArguments(ChocolateyConfiguration config, ChocolateyPackageInformation packageInfo)
1878+
{
1879+
if (!config.Features.UseRememberedArgumentsForUpgrades || string.IsNullOrWhiteSpace(packageInfo.Arguments))
1880+
{
1881+
return config;
1882+
}
1883+
1884+
var packageArgumentsUnencrypted = packageInfo.Arguments.ContainsSafe(" --") && packageInfo.Arguments.ToStringSafe().Length > 4 ? packageInfo.Arguments : NugetEncryptionUtility.DecryptString(packageInfo.Arguments);
1885+
1886+
var sensitiveArgs = true;
1887+
if (!ArgumentsUtility.SensitiveArgumentsProvided(packageArgumentsUnencrypted))
1888+
{
1889+
sensitiveArgs = false;
1890+
this.Log().Debug(ChocolateyLoggers.Verbose, "{0} - Adding remembered arguments: {1}".FormatWith(packageInfo.Package.Id, packageArgumentsUnencrypted.EscapeCurlyBraces()));
1891+
}
1892+
1893+
var packageArgumentsSplit = packageArgumentsUnencrypted.Split(new[] { " --" }, StringSplitOptions.RemoveEmptyEntries);
1894+
var packageArguments = new List<string>();
1895+
foreach (var packageArgument in packageArgumentsSplit.OrEmpty())
1896+
{
1897+
var packageArgumentSplit = packageArgument.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries);
1898+
var optionName = packageArgumentSplit[0].ToStringSafe();
1899+
var optionValue = string.Empty;
1900+
if (packageArgumentSplit.Length == 2)
1901+
{
1902+
optionValue = packageArgumentSplit[1].ToStringSafe().UnquoteSafe();
1903+
if (optionValue.StartsWith("'"))
1904+
{
1905+
optionValue.UnquoteSafe();
1906+
}
1907+
}
1908+
1909+
if (sensitiveArgs)
1910+
{
1911+
this.Log().Debug(ChocolateyLoggers.Verbose, "{0} - Adding '{1}' to arguments. Values not shown due to detected sensitive arguments".FormatWith(packageInfo.Package.Id, optionName.EscapeCurlyBraces()));
1912+
}
1913+
packageArguments.Add("--{0}{1}".FormatWith(optionName, string.IsNullOrWhiteSpace(optionValue) ? string.Empty : "=" + optionValue));
1914+
}
1915+
1916+
var originalConfig = config.DeepCopy();
1917+
var rememberedOptionSet = new OptionSet();
1918+
1919+
rememberedOptionSet
1920+
.Add("pre|prerelease",
1921+
"Prerelease - Include Prereleases? Defaults to false.",
1922+
option => config.Prerelease = option != null)
1923+
.Add("i|ignoredependencies|ignore-dependencies",
1924+
"IgnoreDependencies - Ignore dependencies when installing package(s). Defaults to false.",
1925+
option => config.IgnoreDependencies = option != null)
1926+
.Add("x86|forcex86",
1927+
"ForceX86 - Force x86 (32bit) installation on 64 bit systems. Defaults to false.",
1928+
option => config.ForceX86 = option != null)
1929+
.Add("ia=|installargs=|install-args=|installarguments=|install-arguments=",
1930+
"InstallArguments - Install Arguments to pass to the native installer in the package. Defaults to unspecified.",
1931+
option => config.InstallArguments = option.UnquoteSafe())
1932+
.Add("o|override|overrideargs|overridearguments|override-arguments",
1933+
"OverrideArguments - Should install arguments be used exclusively without appending to current package passed arguments? Defaults to false.",
1934+
option => config.OverrideArguments = option != null)
1935+
.Add("argsglobal|args-global|installargsglobal|install-args-global|applyargstodependencies|apply-args-to-dependencies|apply-install-arguments-to-dependencies",
1936+
"Apply Install Arguments To Dependencies - Should install arguments be applied to dependent packages? Defaults to false.",
1937+
option => config.ApplyInstallArgumentsToDependencies = option != null)
1938+
.Add("params=|parameters=|pkgparameters=|packageparameters=|package-parameters=",
1939+
"PackageParameters - Parameters to pass to the package. Defaults to unspecified.",
1940+
option => config.PackageParameters = option.UnquoteSafe())
1941+
.Add("paramsglobal|params-global|packageparametersglobal|package-parameters-global|applyparamstodependencies|apply-params-to-dependencies|apply-package-parameters-to-dependencies",
1942+
"Apply Package Parameters To Dependencies - Should package parameters be applied to dependent packages? Defaults to false.",
1943+
option => config.ApplyPackageParametersToDependencies = option != null)
1944+
.Add("allowdowngrade|allow-downgrade",
1945+
"AllowDowngrade - Should an attempt at downgrading be allowed? Defaults to false.",
1946+
option => config.AllowDowngrade = option != null)
1947+
.Add("u=|user=",
1948+
"User - used with authenticated feeds. Defaults to empty.",
1949+
option => config.SourceCommand.Username = option.UnquoteSafe())
1950+
.Add("p=|password=",
1951+
"Password - the user's password to the source. Defaults to empty.",
1952+
option => config.SourceCommand.Password = option.UnquoteSafe())
1953+
.Add("cert=",
1954+
"Client certificate - PFX pathname for an x509 authenticated feeds. Defaults to empty. Available in 0.9.10+.",
1955+
option => config.SourceCommand.Certificate = option.UnquoteSafe())
1956+
.Add("cp=|certpassword=",
1957+
"Certificate Password - the client certificate's password to the source. Defaults to empty. Available in 0.9.10+.",
1958+
option => config.SourceCommand.CertificatePassword = option.UnquoteSafe())
1959+
.Add("timeout=|execution-timeout=",
1960+
"CommandExecutionTimeout (in seconds) - The time to allow a command to finish before timing out. Overrides the default execution timeout in the configuration of {0} seconds. '0' for infinite starting in 0.10.4.".FormatWith(config.CommandExecutionTimeoutSeconds.ToString()),
1961+
option =>
1962+
{
1963+
var timeout = 0;
1964+
var timeoutString = option.UnquoteSafe();
1965+
int.TryParse(timeoutString, out timeout);
1966+
if (timeout > 0 || timeoutString.IsEqualTo("0"))
1967+
{
1968+
config.CommandExecutionTimeoutSeconds = timeout;
1969+
}
1970+
})
1971+
.Add("c=|cache=|cachelocation=|cache-location=",
1972+
"CacheLocation - Location for download cache, defaults to %TEMP% or value in chocolatey.config file.",
1973+
option => config.CacheLocation = option.UnquoteSafe())
1974+
.Add("use-system-powershell",
1975+
"UseSystemPowerShell - Execute PowerShell using an external process instead of the built-in PowerShell host. Should only be used when internal host is failing. Available in 0.9.10+.",
1976+
option => config.Features.UsePowerShellHost = option != null);
1977+
1978+
rememberedOptionSet.Parse(packageArguments);
1979+
1980+
// there may be overrides from the user running upgrade
1981+
if (!string.IsNullOrWhiteSpace(originalConfig.PackageParameters))
1982+
{
1983+
config.PackageParameters = originalConfig.PackageParameters;
1984+
}
1985+
1986+
if (!string.IsNullOrWhiteSpace(originalConfig.InstallArguments))
1987+
{
1988+
config.InstallArguments = originalConfig.InstallArguments;
1989+
}
1990+
1991+
if (!string.IsNullOrWhiteSpace(originalConfig.SourceCommand.Username))
1992+
{
1993+
config.SourceCommand.Username = originalConfig.SourceCommand.Username;
1994+
}
1995+
1996+
if (!string.IsNullOrWhiteSpace(originalConfig.SourceCommand.Password))
1997+
{
1998+
config.SourceCommand.Password = originalConfig.SourceCommand.Password;
1999+
}
2000+
2001+
if (!string.IsNullOrWhiteSpace(originalConfig.SourceCommand.Certificate))
2002+
{
2003+
config.SourceCommand.Certificate = originalConfig.SourceCommand.Certificate;
2004+
}
2005+
2006+
if (!string.IsNullOrWhiteSpace(originalConfig.SourceCommand.CertificatePassword))
2007+
{
2008+
config.SourceCommand.CertificatePassword = originalConfig.SourceCommand.CertificatePassword;
2009+
}
2010+
2011+
if (originalConfig.CacheLocationArgumentWasPassed && !string.IsNullOrWhiteSpace(originalConfig.CacheLocation))
2012+
{
2013+
config.CacheLocation = originalConfig.CacheLocation;
2014+
}
2015+
2016+
if (originalConfig.CommandExecutionTimeoutSecondsArgumentWasPassed)
2017+
{
2018+
config.CommandExecutionTimeoutSeconds = originalConfig.CommandExecutionTimeoutSeconds;
2019+
}
2020+
2021+
// We can't override switches because we don't know here if they were set on the command line
2022+
2023+
return config;
2024+
}
2025+
18762026
private bool HasMissingDependency(PackageResult package, List<PackageResult> allLocalPackages)
18772027
{
18782028
foreach (var dependency in package.PackageMetadata.DependencyGroups.SelectMany(d => d.Packages))

0 commit comments

Comments
 (0)