diff --git a/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1 b/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1 index 2eb13a834..e35b5a1f8 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" } diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs index 42a11d382..7455ce198 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs @@ -37,16 +37,20 @@ public abstract class ChocolateyExportCommandSpecsBase : TinySpec protected Mock NugetService = new Mock(); protected Mock FileSystem = new Mock(); protected ChocolateyConfiguration Configuration = new ChocolateyConfiguration(); + protected Mock PackageInfoService = new Mock(); + protected Mock PackageService = new Mock(); public override void Context() { - Command = new ChocolateyExportCommand(NugetService.Object, FileSystem.Object); + Command = new ChocolateyExportCommand(NugetService.Object, FileSystem.Object, PackageInfoService.Object, PackageService.Object); } public void Reset() { NugetService.ResetCalls(); FileSystem.ResetCalls(); + PackageInfoService.ResetCalls(); + PackageService.ResetCalls(); } } @@ -104,6 +108,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 9c1b8e623..8e06c8028 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs @@ -37,11 +37,19 @@ public class ChocolateyExportCommand : ICommand { private readonly INugetService _nugetService; private readonly IFileSystem _fileSystem; - - public ChocolateyExportCommand(INugetService nugetService, IFileSystem fileSystem) + private readonly IChocolateyPackageInformationService _packageInfoService; + private readonly IChocolateyPackageService _packageService; + + public ChocolateyExportCommand( + INugetService nugetService, + IFileSystem fileSystem, + IChocolateyPackageInformationService packageInfoService, + IChocolateyPackageService packageService) { _nugetService = nugetService; _fileSystem = fileSystem; + _packageInfoService = packageInfoService; + _packageService = packageService; } public void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfiguration configuration) @@ -53,6 +61,9 @@ public void ConfigureArgumentParser(OptionSet optionSet, ChocolateyConfiguration .Add("include-version-numbers|include-version", "Include Version Numbers - controls whether or not version numbers for each package appear in generated file. Defaults to false.", option => configuration.ExportCommand.IncludeVersionNumbers = 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) ; } @@ -96,12 +107,14 @@ public void HelpMessage(ChocolateyConfiguration configuration) "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. @@ -132,7 +145,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) @@ -140,6 +153,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( () => { @@ -162,6 +177,40 @@ public void Run(ChocolateyConfiguration configuration) packageElement.Version = packageResult.PackageMetadata.Version.ToString(); } + 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 d008ddd73..cf9c6864b 100644 --- a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs +++ b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs @@ -718,6 +718,7 @@ public sealed class ProxyConfiguration public sealed class ExportCommandConfiguration { public bool IncludeVersionNumbers { get; set; } + public bool IncludeRememberedPackageArguments { get; set; } public string OutputFilePath { get; set; } }