diff --git a/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1 b/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1
index 980d7e7f0a..e2a74cdb7e 100644
--- a/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1
+++ b/src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1
@@ -33,7 +33,7 @@ function script:chocoCmdOperations($commands, $command, $filter, $currentArgumen
where { $_ -like "$filter*" }
}
-$script:someCommands = @('-?','search','list','info','install','outdated','upgrade','uninstall','new','download','optimize','pack','push','sync','-h','--help','pin','source','config','feature','apikey')
+$script:someCommands = @('-?','search','list','info','install','outdated','upgrade','uninstall','new','download','optimize','pack','push','sync','-h','--help','pin','source','config','feature','apikey', 'export')
# ensure these all have a space to start, or they will cause issues
$allcommands = " --debug --verbose --trace --noop --help --accept-license --confirm --limit-output --no-progress --log-file='' --execution-timeout='' --cache-location='' --proxy='' --proxy-user='' --proxy-password='' --proxy-bypass-list='' --proxy-bypass-on-local --force --no-color"
@@ -62,6 +62,7 @@ $commandOptions = @{
download = "--internalize --internalize-all-urls --ignore-dependencies --installed-packages --ignore-unfound-packages --resources-location='' --download-location='' --outputdirectory='' --source='' --version='' --prerelease --user='' --password='' --cert='' --certpassword='' --append-use-original-location --recompile --disable-package-repository-optimizations -?" + $allcommands
sync = "--output-directory='' --id='' --package-id='' -?" + $allcommands
optimize = "--deflate-nupkg-only --id='' -?" + $allcommands
+ export = "--output-file-path='' --include-version-numbers -?" + $allcommands
}
try {
diff --git a/src/chocolatey/chocolatey.csproj b/src/chocolatey/chocolatey.csproj
index fd7a2ad802..ae212d68f5 100644
--- a/src/chocolatey/chocolatey.csproj
+++ b/src/chocolatey/chocolatey.csproj
@@ -101,6 +101,7 @@
Properties\SolutionVersion.cs
+
diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs
new file mode 100644
index 0000000000..6c29a26966
--- /dev/null
+++ b/src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs
@@ -0,0 +1,145 @@
+// Copyright © 2017 - 2018 Chocolatey Software, Inc
+// Copyright © 2011 - 2017 RealDimensions Software, LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+//
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace chocolatey.infrastructure.app.commands
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.IO;
+ using System.Text;
+ using System.Xml;
+ using attributes;
+ using chocolatey.infrastructure.services;
+ using commandline;
+ using configuration;
+ using filesystem;
+ using infrastructure.commands;
+ using logging;
+ using services;
+ using tolerance;
+
+ [CommandFor("export", "exports list of currently installed packages")]
+ public class ChocolateyExportCommand : ICommand
+ {
+ private readonly INugetService _nugetService;
+ private readonly IFileSystem _fileSystem;
+ private readonly IXmlService _xmlService;
+
+ public ChocolateyExportCommand(INugetService nugetService, IFileSystem fileSystem, IXmlService xmlService)
+ {
+ _nugetService = nugetService;
+ _fileSystem = fileSystem;
+ _xmlService = xmlService;
+ }
+
+ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration)
+ {
+ optionSet
+ .Add("o=|output=|output-file-path=",
+ "Output File Path - the path to where the list of currently installed packages should be saved. Defaults to packages.config.",
+ option => configuration.ExportCommand.OutputFilePath = option.remove_surrounding_quotes())
+ .Add("include-version|include-version-numbers",
+ "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)
+ ;
+ }
+
+ public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration)
+ {
+ // Cuurently, no additional argument parsing is required
+ }
+
+ public void handle_validation(ChocolateyConfiguration configuration)
+ {
+ // Currently, no additional validation is required.
+ }
+
+ public void help_message(ChocolateyConfiguration configuration)
+ {
+ this.Log().Info(ChocolateyLoggers.Important, "Export Command");
+ this.Log().Info(@"
+Export all currently installed packages to a file.
+
+This is especially helpful when re-building a machine that was created
+using Chocolatey. Export all packages to a file, and then re-install
+those packages onto a new machine using `choco install packages.config`.
+");
+ "chocolatey".Log().Info(ChocolateyLoggers.Important, "Usage");
+ "chocolatey".Log().Info(@"
+ choco export []
+");
+
+ "chocolatey".Log().Info(ChocolateyLoggers.Important, "Examples");
+ "chocolatey".Log().Info(@"
+ choco export
+ choco export --include-version-numbers
+ choco export --output-file-path=""'c:\temp\packages.config'""
+ choco export --output-file-path=""'c:\temp\packages.config'"" --include-version-numbers
+
+NOTE: See scripting in the command reference (`choco -?`) for how to
+ write proper scripts and integrations.
+
+");
+
+ "chocolatey".Log().Info(ChocolateyLoggers.Important, "Exit Codes");
+ "chocolatey".Log().Info(@"
+Exit codes that normally result from running this command.
+
+Normal:
+ - 0: operation was successful, no issues detected
+ - -1 or 1: an error has occurred
+
+If you find other exit codes that we have not yet documented, please
+ file a ticket so we can document it at
+ https://github.com/chocolatey/choco/issues/new/choose.
+
+");
+
+ "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches");
+ }
+
+ public bool may_require_admin_access()
+ {
+ return false;
+ }
+
+ 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));
+ }
+
+ public void run(ChocolateyConfiguration configuration)
+ {
+ var packageResults = _nugetService.get_all_installed_packages(configuration);
+ var packagesConfig = new PackagesConfigFileSettings();
+
+ packagesConfig.Packages = new HashSet();
+
+ foreach (var packageResult in packageResults)
+ {
+ var packagesConfigFile = new PackagesConfigFilePackageSetting();
+ packagesConfigFile.Id = packageResult.Package.Id;
+ packagesConfigFile.Version = packageResult.Package.Version.ToString();
+ packagesConfigFile.IncludeVersion = configuration.ExportCommand.IncludeVersionNumbers;
+
+ packagesConfig.Packages.Add(packagesConfigFile);
+ }
+
+ _xmlService.serialize(packagesConfig, configuration.ExportCommand.OutputFilePath);
+ }
+ }
+}
diff --git a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs
index c5cc33f73f..52bf9c74d7 100644
--- a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs
+++ b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs
@@ -50,6 +50,7 @@ public ChocolateyConfiguration()
PinCommand = new PinCommandConfiguration();
OutdatedCommand = new OutdatedCommandConfiguration();
Proxy = new ProxyConfiguration();
+ ExportCommand = new ExportCommandConfiguration();
#if DEBUG
AllowUnofficialBuild = true;
#endif
@@ -334,6 +335,8 @@ private void append_output(StringBuilder propertyValues, string append)
///
public OutdatedCommandConfiguration OutdatedCommand { get; set; }
+ public ExportCommandConfiguration ExportCommand { get; set; }
+
///
/// Configuration related specifically to proxies.
///
@@ -545,4 +548,17 @@ public sealed class ProxyConfiguration
public string BypassList { get; set; }
public bool BypassOnLocal { get; set; }
}
+
+ [Serializable]
+ public sealed class ExportCommandConfiguration
+ {
+ public ExportCommandConfiguration()
+ {
+ OutputFilePath = "packages.config";
+ }
+
+ public bool IncludeVersionNumbers { get; set; }
+
+ public string OutputFilePath { get; set; }
+ }
}
\ No newline at end of file
diff --git a/src/chocolatey/infrastructure.app/configuration/PackagesConfigFilePackageSetting.cs b/src/chocolatey/infrastructure.app/configuration/PackagesConfigFilePackageSetting.cs
index ac0a002055..765c299fef 100644
--- a/src/chocolatey/infrastructure.app/configuration/PackagesConfigFilePackageSetting.cs
+++ b/src/chocolatey/infrastructure.app/configuration/PackagesConfigFilePackageSetting.cs
@@ -58,5 +58,53 @@ public sealed class PackagesConfigFilePackageSetting
[XmlAttribute(AttributeName = "disabled")]
public bool Disabled { get; set; }
+
+ [XmlIgnore]
+ public bool IncludeVersion { get; set; }
+
+ public bool ShouldSerializeVersion()
+ {
+ return IncludeVersion;
+ }
+
+ public bool ShouldSerializeInstallArguments()
+ {
+ return false;
+ }
+
+ public bool ShouldSerializePackageParameters()
+ {
+ return false;
+ }
+
+ public bool ShouldSerializeApplyPackageParametersToDependencies()
+ {
+ return false;
+ }
+
+ public bool ShouldSerializeApplyInstallArgumentsToDependencies()
+ {
+ return false;
+ }
+
+ public bool ShouldSerializeForceX86()
+ {
+ return false;
+ }
+
+ public bool ShouldSerializeAllowMultipleVersions()
+ {
+ return false;
+ }
+
+ public bool ShouldSerializeIgnoreDependencies()
+ {
+ return false;
+ }
+
+ public bool ShouldSerializeDisabled()
+ {
+ return false;
+ }
}
}
diff --git a/src/chocolatey/infrastructure.app/registration/ContainerBinding.cs b/src/chocolatey/infrastructure.app/registration/ContainerBinding.cs
index 67ffc551b5..405be6193f 100644
--- a/src/chocolatey/infrastructure.app/registration/ContainerBinding.cs
+++ b/src/chocolatey/infrastructure.app/registration/ContainerBinding.cs
@@ -95,7 +95,8 @@ public void RegisterComponents(Container container)
new ChocolateyApiKeyCommand(container.GetInstance()),
new ChocolateyUnpackSelfCommand(container.GetInstance()),
new ChocolateyVersionCommand(container.GetInstance()),
- new ChocolateyUpdateCommand(container.GetInstance())
+ new ChocolateyUpdateCommand(container.GetInstance()),
+ new ChocolateyExportCommand(container.GetInstance(), container.GetInstance(), container.GetInstance())
};
return list.AsReadOnly();
}, Lifestyle.Singleton);