Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(#2886)(#2761) Improve remembered arguments handling #3003

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -419,11 +419,16 @@ private static void SetGlobalOptions(IList<string> args, ChocolateyConfiguration
if (timeout > 0 || timeoutString.IsEqualTo("0"))
{
config.CommandExecutionTimeoutSeconds = timeout;
config.CommandExecutionTimeoutSecondsArgumentWasPassed = true;
}
})
.Add("c=|cache=|cachelocation=|cache-location=",
"CacheLocation - Location for download cache, defaults to %TEMP% or value in chocolatey.config file.",
option => config.CacheLocation = option.UnquoteSafe())
option =>
{
config.CacheLocation = option.UnquoteSafe();
config.CacheLocationArgumentWasPassed = true;
})
.Add("allowunofficial|allow-unofficial|allowunofficialbuild|allow-unofficial-build",
"AllowUnofficialBuild - When not using the official build you must set this flag for choco to continue.",
option => config.AllowUnofficialBuild = option != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,10 @@ private void AppendOutput(StringBuilder propertyValues, string append)

// configuration set variables
public string CacheLocation { get; set; }
public bool CacheLocationArgumentWasPassed { get; set; }

public int CommandExecutionTimeoutSeconds { get; set; }
public bool CommandExecutionTimeoutSecondsArgumentWasPassed { get; set; }
public int WebRequestTimeoutSeconds { get; set; }
public string DefaultTemplateName { get; set; }

Expand Down
11 changes: 11 additions & 0 deletions src/chocolatey/infrastructure.app/services/INugetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using chocolatey.infrastructure.app.configuration;
using chocolatey.infrastructure.app.domain;
using chocolatey.infrastructure.results;

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


/// <summary>
/// Gets the configuration from remembered arguments
/// </summary>
/// <param name="config">The original configuration.</param>
/// <param name="packageInfo">The package information.</param>
/// <returns>The modified configuration, so it can be used</returns>
ChocolateyConfiguration GetPackageConfigFromRememberedArguments(ChocolateyConfiguration config,
ChocolateyPackageInformation packageInfo);

#pragma warning disable IDE0022, IDE1006
[Obsolete("This overload is deprecated and will be removed in v3.")]
ConcurrentDictionary<string, PackageResult> get_outdated(ChocolateyConfiguration config);
Expand Down
198 changes: 184 additions & 14 deletions src/chocolatey/infrastructure.app/services/NugetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ public void InstallDryRun(ChocolateyConfiguration config, Action<PackageResult,
if (packageNames.Count == 1)
{
var packageName = packageNames.DefaultIfEmpty(string.Empty).FirstOrDefault();
if (packageName.EndsWith(NuGetConstants.PackageExtension) || packageName.EndsWith(PackagingConstants.ManifestExtension))
if (packageName.EndsWith(NuGetConstants.PackageExtension, StringComparison.OrdinalIgnoreCase) || packageName.EndsWith(PackagingConstants.ManifestExtension, StringComparison.OrdinalIgnoreCase))
{
this.Log().Warn(ChocolateyLoggers.Important, "DEPRECATION WARNING");
this.Log().Warn(InstallWithFilePathDeprecationMessage);
Expand All @@ -534,7 +534,7 @@ public void InstallDryRun(ChocolateyConfiguration config, Action<PackageResult,

config.Sources = _fileSystem.GetDirectoryName(_fileSystem.GetFullPath(packageName));

if (packageName.EndsWith(PackagingConstants.ManifestExtension))
if (packageName.EndsWith(PackagingConstants.ManifestExtension, StringComparison.OrdinalIgnoreCase))
{
packageNames.Add(_fileSystem.GetFilenameWithoutExtension(packageName));

Expand Down Expand Up @@ -578,7 +578,7 @@ public void InstallDryRun(ChocolateyConfiguration config, Action<PackageResult,

var installedPackage = allLocalPackages.FirstOrDefault(p => p.Name.IsEqualTo(packageName));

if (Platform.GetPlatform() != PlatformType.Windows && !packageName.EndsWith(".template"))
if (Platform.GetPlatform() != PlatformType.Windows && !packageName.EndsWith(".template", StringComparison.OrdinalIgnoreCase))
{
var logMessage = "{0} is not a supported package on non-Windows systems.{1}Only template packages are currently supported.".FormatWith(packageName, Environment.NewLine);
this.Log().Warn(ChocolateyLoggers.Important, logMessage);
Expand Down Expand Up @@ -1116,7 +1116,7 @@ public virtual void EnsureBackupDirectoryRemoved(string packageName)
continue;
}

SetConfigFromRememberedArguments(config, pkgInfo);
config = GetPackageConfigFromRememberedArguments(config, pkgInfo);
var pathResolver = NugetCommon.GetPathResolver(_fileSystem);
var nugetProject = new FolderNuGetProject(ApplicationParameters.PackagesLocation, pathResolver, NuGetFramework.AnyFramework);

Expand Down Expand Up @@ -1254,12 +1254,12 @@ public virtual void EnsureBackupDirectoryRemoved(string packageName)
var logMessage = "{0} is pinned. Skipping pinned package.".FormatWith(packageName);
packageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage));
packageResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage));

if (config.RegularOutput)
{
this.Log().Warn(ChocolateyLoggers.Important, logMessage);
}

continue;
}
else
Expand All @@ -1271,7 +1271,7 @@ public virtual void EnsureBackupDirectoryRemoved(string packageName)
{
this.Log().Warn(ChocolateyLoggers.Important, logMessage);
}

config.PinPackage = true;
}
}
Expand Down Expand Up @@ -1344,7 +1344,7 @@ public virtual void EnsureBackupDirectoryRemoved(string packageName)
}

var removedSources = new HashSet<SourcePackageDependencyInfo>();

if (!config.UpgradeCommand.IgnorePinned)
{
RemovePinnedSourceDependencies(sourcePackageDependencyInfos, allLocalPackages);
Expand Down Expand Up @@ -1780,12 +1780,7 @@ public virtual void EnsureBackupDirectoryRemoved(string packageName)
return outdatedPackages;
}

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

// there may be overrides from the user running upgrade
if (!string.IsNullOrWhiteSpace(originalConfig.PackageParameters))
{
config.PackageParameters = originalConfig.PackageParameters;
}

if (!string.IsNullOrWhiteSpace(originalConfig.InstallArguments))
{
config.InstallArguments = originalConfig.InstallArguments;
}

if (!string.IsNullOrWhiteSpace(originalConfig.SourceCommand.Username))
{
config.SourceCommand.Username = originalConfig.SourceCommand.Username;
Expand All @@ -1850,9 +1855,174 @@ protected virtual ChocolateyConfiguration SetConfigFromRememberedArguments(Choco
config.SourceCommand.CertificatePassword = originalConfig.SourceCommand.CertificatePassword;
}

if (originalConfig.CacheLocationArgumentWasPassed && !string.IsNullOrWhiteSpace(originalConfig.CacheLocation))
{
config.CacheLocation = originalConfig.CacheLocation;
}

if (originalConfig.CommandExecutionTimeoutSecondsArgumentWasPassed)
{
config.CommandExecutionTimeoutSeconds = originalConfig.CommandExecutionTimeoutSeconds;
}

return originalConfig;
}

/// <summary>
/// Gets the configuration from remembered arguments
/// </summary>
/// <param name="config">The original configuration.</param>
/// <param name="packageInfo">The package information.</param>
/// <returns>The modified configuration, so it can be used</returns>
public virtual ChocolateyConfiguration GetPackageConfigFromRememberedArguments(ChocolateyConfiguration config, ChocolateyPackageInformation packageInfo)
{
if (!config.Features.UseRememberedArgumentsForUpgrades || string.IsNullOrWhiteSpace(packageInfo.Arguments))
{
return config;
}

var packageArgumentsUnencrypted = packageInfo.Arguments.ContainsSafe(" --") && packageInfo.Arguments.ToStringSafe().Length > 4 ? packageInfo.Arguments : NugetEncryptionUtility.DecryptString(packageInfo.Arguments);

var sensitiveArgs = true;
if (!ArgumentsUtility.SensitiveArgumentsProvided(packageArgumentsUnencrypted))
{
sensitiveArgs = false;
this.Log().Debug(ChocolateyLoggers.Verbose, "{0} - Adding remembered arguments: {1}".FormatWith(packageInfo.Package.Id, packageArgumentsUnencrypted.EscapeCurlyBraces()));
}

var packageArgumentsSplit = packageArgumentsUnencrypted.Split(new[] { " --" }, StringSplitOptions.RemoveEmptyEntries);
var packageArguments = new List<string>();
foreach (var packageArgument in packageArgumentsSplit.OrEmpty())
{
var packageArgumentSplit = packageArgument.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries);
var optionName = packageArgumentSplit[0].ToStringSafe();
var optionValue = string.Empty;
if (packageArgumentSplit.Length == 2)
{
optionValue = packageArgumentSplit[1].ToStringSafe().UnquoteSafe();
if (optionValue.StartsWith("'"))
{
optionValue.UnquoteSafe();
}
}

if (sensitiveArgs)
{
this.Log().Debug(ChocolateyLoggers.Verbose, "{0} - Adding '{1}' to arguments. Values not shown due to detected sensitive arguments".FormatWith(packageInfo.Package.Id, optionName.EscapeCurlyBraces()));
}
packageArguments.Add("--{0}{1}".FormatWith(optionName, string.IsNullOrWhiteSpace(optionValue) ? string.Empty : "=" + optionValue));
}

var originalConfig = config.DeepCopy();
var rememberedOptionSet = new OptionSet();

rememberedOptionSet
.Add("pre|prerelease",
"Prerelease - Include Prereleases? Defaults to false.",
option => config.Prerelease = option != null)
.Add("i|ignoredependencies|ignore-dependencies",
"IgnoreDependencies - Ignore dependencies when installing package(s). Defaults to false.",
option => config.IgnoreDependencies = option != null)
.Add("x86|forcex86",
"ForceX86 - Force x86 (32bit) installation on 64 bit systems. Defaults to false.",
option => config.ForceX86 = option != null)
.Add("ia=|installargs=|install-args=|installarguments=|install-arguments=",
"InstallArguments - Install Arguments to pass to the native installer in the package. Defaults to unspecified.",
option => config.InstallArguments = option.UnquoteSafe())
.Add("o|override|overrideargs|overridearguments|override-arguments",
"OverrideArguments - Should install arguments be used exclusively without appending to current package passed arguments? Defaults to false.",
option => config.OverrideArguments = option != null)
.Add("argsglobal|args-global|installargsglobal|install-args-global|applyargstodependencies|apply-args-to-dependencies|apply-install-arguments-to-dependencies",
"Apply Install Arguments To Dependencies - Should install arguments be applied to dependent packages? Defaults to false.",
option => config.ApplyInstallArgumentsToDependencies = option != null)
.Add("params=|parameters=|pkgparameters=|packageparameters=|package-parameters=",
"PackageParameters - Parameters to pass to the package. Defaults to unspecified.",
option => config.PackageParameters = option.UnquoteSafe())
.Add("paramsglobal|params-global|packageparametersglobal|package-parameters-global|applyparamstodependencies|apply-params-to-dependencies|apply-package-parameters-to-dependencies",
"Apply Package Parameters To Dependencies - Should package parameters be applied to dependent packages? Defaults to false.",
option => config.ApplyPackageParametersToDependencies = option != null)
.Add("allowdowngrade|allow-downgrade",
"AllowDowngrade - Should an attempt at downgrading be allowed? Defaults to false.",
option => config.AllowDowngrade = option != null)
.Add("u=|user=",
"User - used with authenticated feeds. Defaults to empty.",
option => config.SourceCommand.Username = option.UnquoteSafe())
.Add("p=|password=",
"Password - the user's password to the source. Defaults to empty.",
option => config.SourceCommand.Password = option.UnquoteSafe())
.Add("cert=",
"Client certificate - PFX pathname for an x509 authenticated feeds. Defaults to empty. Available in 0.9.10+.",
option => config.SourceCommand.Certificate = option.UnquoteSafe())
.Add("cp=|certpassword=",
"Certificate Password - the client certificate's password to the source. Defaults to empty. Available in 0.9.10+.",
option => config.SourceCommand.CertificatePassword = option.UnquoteSafe())
.Add("timeout=|execution-timeout=",
"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()),
option =>
{
var timeout = 0;
var timeoutString = option.UnquoteSafe();
int.TryParse(timeoutString, out timeout);
if (timeout > 0 || timeoutString.IsEqualTo("0"))
{
config.CommandExecutionTimeoutSeconds = timeout;
}
})
.Add("c=|cache=|cachelocation=|cache-location=",
"CacheLocation - Location for download cache, defaults to %TEMP% or value in chocolatey.config file.",
option => config.CacheLocation = option.UnquoteSafe())
.Add("use-system-powershell",
"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+.",
option => config.Features.UsePowerShellHost = option != null);

rememberedOptionSet.Parse(packageArguments);

// there may be overrides from the user running upgrade
if (!string.IsNullOrWhiteSpace(originalConfig.PackageParameters))
{
config.PackageParameters = originalConfig.PackageParameters;
}

if (!string.IsNullOrWhiteSpace(originalConfig.InstallArguments))
{
config.InstallArguments = originalConfig.InstallArguments;
}

if (!string.IsNullOrWhiteSpace(originalConfig.SourceCommand.Username))
{
config.SourceCommand.Username = originalConfig.SourceCommand.Username;
}

if (!string.IsNullOrWhiteSpace(originalConfig.SourceCommand.Password))
{
config.SourceCommand.Password = originalConfig.SourceCommand.Password;
}

if (!string.IsNullOrWhiteSpace(originalConfig.SourceCommand.Certificate))
{
config.SourceCommand.Certificate = originalConfig.SourceCommand.Certificate;
}

if (!string.IsNullOrWhiteSpace(originalConfig.SourceCommand.CertificatePassword))
{
config.SourceCommand.CertificatePassword = originalConfig.SourceCommand.CertificatePassword;
}

if (originalConfig.CacheLocationArgumentWasPassed && !string.IsNullOrWhiteSpace(originalConfig.CacheLocation))
{
config.CacheLocation = originalConfig.CacheLocation;
}

if (originalConfig.CommandExecutionTimeoutSecondsArgumentWasPassed)
{
config.CommandExecutionTimeoutSeconds = originalConfig.CommandExecutionTimeoutSeconds;
}

// We can't override switches because we don't know here if they were set on the command line

return config;
}

private bool HasMissingDependency(PackageResult package, List<PackageResult> allLocalPackages)
{
foreach (var dependency in package.PackageMetadata.DependencyGroups.SelectMany(d => d.Packages))
Expand Down
Loading