From b549b47d7b4bb43e1328329011c09182f85fe6e7 Mon Sep 17 00:00:00 2001 From: TheCakeIsNaOH Date: Tue, 9 Jan 2024 18:18:14 -0600 Subject: [PATCH] (#2503) Add ability to export remembered arguments This adds the --include-remembered-arguments option which is used to export any remembered arguments. It reuses the GetPackageConfigFromRememberedArguments method in the NugetService to read and parse the remembered arguments. --- .../helpers/ChocolateyTabExpansion.ps1 | 2 +- .../commands/ChocolateyExportCommandSpecs.cs | 17 ++- .../commands/ChocolateyExportCommand.cs | 108 +++++++++++++++++- .../configuration/ChocolateyConfiguration.cs | 1 + 4 files changed, 123 insertions(+), 5 deletions(-) diff --git a/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1 b/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1 index 149bcd0827..50971364c8 100644 --- a/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1 +++ b/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1 @@ -56,7 +56,7 @@ $commandOptions = @{ config = "--name='' --value=''" feature = "--name=''" apikey = "--source='' --api-key='' --remove" - export = "--include-version-numbers --output-file-path=''" + export = "--include-version-numbers --output-file-path='' --include-remembered-arguments" template = "--name=''" cache = "--expired" rule = "--name=''" diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs index d91939a8e6..c50fe41d23 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs @@ -41,16 +41,19 @@ public abstract class ChocolateyExportCommandSpecsBase : TinySpec protected Mock ContainerResolver = new Mock(); protected Mock RegistryService = new Mock(); protected Mock PackageInfoService = new Mock(); + protected Mock PackageService = new Mock(); public override void Context() { - Command = new ChocolateyExportCommand(NugetService.Object, FileSystem.Object, ContainerResolver.Object, RegistryService.Object, PackageInfoService.Object); + Command = new ChocolateyExportCommand(NugetService.Object, FileSystem.Object, ContainerResolver.Object, RegistryService.Object, PackageInfoService.Object, PackageService.Object); } public void Reset() { NugetService.ResetCalls(); FileSystem.ResetCalls(); + PackageInfoService.ResetCalls(); + PackageService.ResetCalls(); } } @@ -108,6 +111,18 @@ public void Should_add_include_version_to_the_option_set() { _optionSet.Contains("include-version").Should().BeTrue(); } + + [Fact] + public void Should_add_include_arguments_to_the_option_set() + { + _optionSet.Contains("include-arguments").Should().BeTrue(); + } + + [Fact] + public void Should_add_include_remembered_arguments_to_the_option_set() + { + _optionSet.Contains("include-remembered-arguments").Should().BeTrue(); + } } public class When_handling_additional_argument_parsing : ChocolateyExportCommandSpecsBase diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs index ff6006c412..38b5bf0b52 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs @@ -46,14 +46,22 @@ public class ChocolateyExportCommand : ICommand private readonly IContainerResolver _containerResolver; private readonly IRegistryService _registryService; private readonly IChocolateyPackageInformationService _packageInfoService; - - public ChocolateyExportCommand(INugetService nugetService, IFileSystem fileSystem, IContainerResolver containerResolver, IRegistryService registryService, IChocolateyPackageInformationService packageInfoService) + private readonly IChocolateyPackageService _packageService; + + public ChocolateyExportCommand( + INugetService nugetService, + IFileSystem fileSystem, + IContainerResolver containerResolver, + IRegistryService registryService, + IChocolateyPackageInformationService packageInfoService, + IChocolateyPackageService packageService) { _nugetService = nugetService; _fileSystem = fileSystem; _containerResolver = containerResolver; _registryService = registryService; _packageInfoService = packageInfoService; + _packageService = packageService; } public void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfiguration configuration) @@ -71,6 +79,9 @@ public void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfiguration .Add("include-alternative-sources", "IncludeAlternativeSources - Includes software from alternative sources which are managed by Chocolatey CLI.", option => configuration.ExportCommand.IncludeAlternativeSources = option != null) + .Add("include-arguments|include-remembered-arguments", + "Include Remembered Arguments - controls whether or not remembered arguments for each package appear in generated file. Defaults to false. Available in 2.3.0+", + option => configuration.ExportCommand.IncludeRememberedPackageArguments = option != null) ; } @@ -114,12 +125,14 @@ choco export [] "chocolatey".Log().Info(@" choco export choco export --include-version-numbers + choco export --include-version-numbers --include-remembered-arguments choco export ""'c:\temp\packages.config'"" choco export ""'c:\temp\packages.config'"" --include-version-numbers choco export -o=""'c:\temp\packages.config'"" choco export -o=""'c:\temp\packages.config'"" --include-version-numbers choco export --output-file-path=""'c:\temp\packages.config'"" choco export --output-file-path=""'c:\temp\packages.config'"" --include-version-numbers + choco export --output-file-path=""""'c:\temp\packages.config'"""" --include-remembered-arguments NOTE: See scripting in the command reference (`choco -?`) for how to write proper scripts and integrations. @@ -150,7 +163,7 @@ public bool MayRequireAdminAccess() public void DryRun(ChocolateyConfiguration configuration) { - this.Log().Info("Export would have been with options: {0} Output File Path={1}{0} Include Version Numbers:{2}".FormatWith(Environment.NewLine, configuration.ExportCommand.OutputFilePath, configuration.ExportCommand.IncludeVersionNumbers)); + this.Log().Info("Export would have been with options: {0} Output File Path={1}{0} Include Version Numbers:{2}{0} Include Remembered Arguments: {3}".FormatWith(Environment.NewLine, configuration.ExportCommand.OutputFilePath, configuration.ExportCommand.IncludeVersionNumbers, configuration.ExportCommand.IncludeRememberedPackageArguments)); } public void Run(ChocolateyConfiguration configuration) @@ -158,6 +171,8 @@ public void Run(ChocolateyConfiguration configuration) var installedPackages = _nugetService.GetInstalledPackages(configuration); var xmlWriterSettings = new XmlWriterSettings { Indent = true, Encoding = new UTF8Encoding(false) }; + configuration.CreateBackup(); + FaultTolerance.TryCatchWithLoggingException( () => { @@ -182,6 +197,93 @@ public void Run(ChocolateyConfiguration configuration) xw.WriteAttributeString("sourceType", "nuget"); + if (configuration.ExportCommand.IncludeRememberedPackageArguments) + { + var pkgInfo = _packageInfoService.Get(packageResult.PackageMetadata); + configuration.Features.UseRememberedArgumentsForUpgrades = true; + var rememberedConfig = _nugetService.GetPackageConfigFromRememberedArguments(configuration, pkgInfo); + + // Mirrors the arguments captured in ChocolateyPackageService.CaptureArguments() + if (configuration.Prerelease) + { + packageElement.Prerelease = true; + } + + if (configuration.IgnoreDependencies) + { + packageElement.IgnoreDependencies = true; + } + + if (configuration.ForceX86) + { + packageElement.ForceX86 = true; + } + + if (!string.IsNullOrWhiteSpace(configuration.InstallArguments)) + { + packageElement.InstallArguments = configuration.InstallArguments; + } + + if (configuration.OverrideArguments) + { + packageElement.OverrideArguments = true; + } + + if (configuration.ApplyInstallArgumentsToDependencies) + { + packageElement.ApplyInstallArgumentsToDependencies = true; + } + + if (!string.IsNullOrWhiteSpace(configuration.PackageParameters)) + { + packageElement.PackageParameters = configuration.PackageParameters; + } + + if (configuration.ApplyPackageParametersToDependencies) + { + packageElement.ApplyPackageParametersToDependencies = true; + } + + if (configuration.AllowDowngrade) + { + packageElement.AllowDowngrade = true; + } + + if (!string.IsNullOrWhiteSpace(configuration.SourceCommand.Username)) + { + packageElement.User = configuration.SourceCommand.Username; + } + + if (!string.IsNullOrWhiteSpace(configuration.SourceCommand.Password)) + { + packageElement.Password = configuration.SourceCommand.Password; + } + + if (!string.IsNullOrWhiteSpace(configuration.SourceCommand.Certificate)) + { + packageElement.Cert = configuration.SourceCommand.Certificate; + } + + if (!string.IsNullOrWhiteSpace(configuration.SourceCommand.CertificatePassword)) + { + packageElement.CertPassword = configuration.SourceCommand.CertificatePassword; + } + + // Arguments from the global options set + if (configuration.CommandExecutionTimeoutSeconds != ApplicationParameters.DefaultWaitForExitInSeconds) + { + packageElement.ExecutionTimeout = configuration.CommandExecutionTimeoutSeconds; + } + + // This was discussed in the PR, and because it is potentially system specific, it should not be included in the exported file + // if (!string.IsNullOrWhiteSpace(configuration.CacheLocation)) packageElement.CacheLocation = configuration.CacheLocation; + // if (configuration.Features.FailOnStandardError) packageElement.FailOnStderr = true; + // if (!configuration.Features.UsePowerShellHost) packageElement.UseSystemPowershell = true; + + // Make sure to reset the configuration so as to be able to parse the next set of remembered arguments + configuration.RevertChanges(); + } + packagesConfig.Packages.Add(packageElement); } diff --git a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs index 54d60ee702..c9cf415784 100644 --- a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs +++ b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs @@ -736,6 +736,7 @@ public sealed class ProxyConfiguration public sealed class ExportCommandConfiguration { public bool IncludeVersionNumbers { get; set; } + public bool IncludeRememberedPackageArguments { get; set; } public string OutputFilePath { get; set; }