diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs index ee28daa473..7bcc4a673d 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyExportCommandSpecs.cs @@ -36,16 +36,18 @@ 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(); public override void Context() { - command = new ChocolateyExportCommand(nugetService.Object, fileSystem.Object); + command = new ChocolateyExportCommand(nugetService.Object, fileSystem.Object, packageInfoService.Object); } public void reset() { nugetService.ResetCalls(); fileSystem.ResetCalls(); + packageInfoService.ResetCalls(); } } @@ -103,6 +105,18 @@ public void should_add_include_version_to_the_option_set() { optionSet.Contains("include-version").ShouldBeTrue(); } + + [Fact] + public void should_add_include_arguments_to_the_option_set() + { + optionSet.Contains("include-arguments").ShouldBeTrue(); + } + + [Fact] + public void should_add_include_remembered_arguments_to_the_option_set() + { + optionSet.Contains("include-remembered-arguments").ShouldBeTrue(); + } } 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 f27562258e..fffb495995 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs @@ -36,11 +36,14 @@ public class ChocolateyExportCommand : ICommand { private readonly INugetService _nugetService; private readonly IFileSystem _fileSystem; + private readonly IChocolateyPackageInformationService _packageInfoService; + private readonly IChocolateyPackageService _packageService; - public ChocolateyExportCommand(INugetService nugetService, IFileSystem fileSystem) + public ChocolateyExportCommand(INugetService nugetService, IFileSystem fileSystem, IChocolateyPackageInformationService packageInfoService) { _nugetService = nugetService; _fileSystem = fileSystem; + _packageInfoService = packageInfoService; } public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) @@ -52,6 +55,9 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati .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.", + option => configuration.ExportCommand.IncludeRememberedPackageArguments = option != null) ; } @@ -97,12 +103,14 @@ public void help_message(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. @@ -133,13 +141,24 @@ public bool may_require_admin_access() public void noop(ChocolateyConfiguration configuration) { - this.Log().Info("Export would have been with options: {0} Output File Path={1}{0} Include Version Numbers:{2}".format_with(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}".format_with(Environment.NewLine, configuration.ExportCommand.OutputFilePath, configuration.ExportCommand.IncludeVersionNumbers, configuration.ExportCommand.IncludeRememberedPackageArguments)); } public void run(ChocolateyConfiguration configuration) { var packageResults = _nugetService.get_all_installed_packages(configuration); var settings = new XmlWriterSettings { Indent = true, Encoding = new UTF8Encoding(false) }; + var originalConfiguration = configuration.deep_copy(); + + if (configuration.ExportCommand.IncludeRememberedPackageArguments) + { + // The -o argument from the export command options set interferes with the -o argument from the install command options set. + ConfigurationOptions.OptionSet.Remove("o"); + + //Add the options set from the install command. + var installCommand = new ChocolateyInstallCommand(_packageService); + installCommand.configure_argument_parser(ConfigurationOptions.OptionSet, configuration); + } FaultTolerance.try_catch_with_logging_exception( () => @@ -161,6 +180,49 @@ public void run(ChocolateyConfiguration configuration) xw.WriteAttributeString("version", packageResult.Package.Version.ToString()); } + if (configuration.ExportCommand.IncludeRememberedPackageArguments) + { + var pkgInfo = _packageInfoService.get_package_information(packageResult.Package); + configuration.Features.UseRememberedArgumentsForUpgrades = true; + _nugetService.set_package_config_for_upgrade(configuration, pkgInfo); + + //Mirrors the arguments captured in ChocolateyPackageService.capture_arguments() + + if (configuration.Prerelease) xw.WriteAttributeString("prerelease", "true"); + if (configuration.IgnoreDependencies) xw.WriteAttributeString("ignoreDependencies", "true"); + if (configuration.ForceX86) xw.WriteAttributeString("forceX86", "true"); + + if (!string.IsNullOrWhiteSpace(configuration.InstallArguments)) xw.WriteAttributeString("installArguments", configuration.InstallArguments); + if (configuration.OverrideArguments) xw.WriteAttributeString("overrideArguments", "true"); + if (configuration.ApplyInstallArgumentsToDependencies) xw.WriteAttributeString("applyInstallArgumentsToDependencies", "true"); + + if (!string.IsNullOrWhiteSpace(configuration.PackageParameters)) xw.WriteAttributeString("packageParameters", configuration.PackageParameters); + if (configuration.ApplyPackageParametersToDependencies) xw.WriteAttributeString("applyPackageParametersToDependencies", "true"); + + if (configuration.AllowDowngrade) xw.WriteAttributeString("allowDowngrade", "true"); + if (configuration.AllowMultipleVersions) xw.WriteAttributeString("allowMultipleVersions", "true"); + + if (!string.IsNullOrWhiteSpace(configuration.SourceCommand.Username)) xw.WriteAttributeString("user", configuration.SourceCommand.Username); + if (!string.IsNullOrWhiteSpace(configuration.SourceCommand.Password)) xw.WriteAttributeString("password", configuration.SourceCommand.Password); + if (!string.IsNullOrWhiteSpace(configuration.SourceCommand.Certificate)) xw.WriteAttributeString("cert", configuration.SourceCommand.Certificate); + if (!string.IsNullOrWhiteSpace(configuration.SourceCommand.CertificatePassword)) xw.WriteAttributeString("certPassword", configuration.SourceCommand.CertificatePassword); + + //Arguments from the global options set + if (configuration.CommandExecutionTimeoutSeconds != ApplicationParameters.DefaultWaitForExitInSeconds) + { + xw.WriteAttributeString("timeout",configuration.CommandExecutionTimeoutSeconds.to_string()); + } + + //TODO, should this be exported? It seems rather system specific + //if (!string.IsNullOrWhiteSpace(configuration.CacheLocation)) xw.WriteAttributeString("cacheLocation", configuration.CacheLocation); + + if (configuration.Features.FailOnStandardError) xw.WriteAttributeString("failOnStderr", "true"); + if (!configuration.Features.UsePowerShellHost) xw.WriteAttributeString("useSystemPowershell", "true"); + + //Make sure to reset the configuration + configuration = originalConfiguration.deep_copy(); + } + xw.WriteEndElement(); } diff --git a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs index 53c89ad0d2..b336591234 100644 --- a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs +++ b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs @@ -560,6 +560,7 @@ public sealed class ProxyConfiguration public sealed class ExportCommandConfiguration { public bool IncludeVersionNumbers { get; set; } + public bool IncludeRememberedPackageArguments { get; set; } public string OutputFilePath { get; set; } } diff --git a/src/chocolatey/infrastructure.app/registration/ContainerBinding.cs b/src/chocolatey/infrastructure.app/registration/ContainerBinding.cs index a88f129ea4..384ee7703a 100644 --- a/src/chocolatey/infrastructure.app/registration/ContainerBinding.cs +++ b/src/chocolatey/infrastructure.app/registration/ContainerBinding.cs @@ -95,7 +95,7 @@ public void RegisterComponents(Container container) new ChocolateyFeatureCommand(container.GetInstance()), new ChocolateyApiKeyCommand(container.GetInstance()), new ChocolateyUnpackSelfCommand(container.GetInstance()), - new ChocolateyExportCommand(container.GetInstance(), container.GetInstance()), + new ChocolateyExportCommand(container.GetInstance(), container.GetInstance(), container.GetInstance()), new ChocolateyTemplateCommand(container.GetInstance()) }; return list.AsReadOnly();