Skip to content

Commit

Permalink
(GH-357) Add Export Command
Browse files Browse the repository at this point in the history
This will allow the creation of a packages.config file of all the
currently installed packages on the machine.  Usage of this command
will be:

choco export -o c:/temp/packages.config --include-version-numbers

This command is particularly useful when re-building a machine.  i.e.
First export all packages currently installed on machine, and then
replay this packages.config via choco install packages.config on new
machine.

Co-authored-by: mwallner <[email protected]>
  • Loading branch information
gep13 and mwallner committed May 31, 2019
1 parent 27d14b3 commit dc18d24
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/chocolatey.resources/helpers/ChocolateyTabExpansion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/chocolatey/chocolatey.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
<Link>Properties\SolutionVersion.cs</Link>
</Compile>
<Compile Include="AssemblyExtensions.cs" />
<Compile Include="infrastructure.app\commands\ChocolateyExportCommand.cs" />
<Compile Include="infrastructure.app\commands\ChocolateyInfoCommand.cs" />
<Compile Include="infrastructure\cryptography\DefaultEncryptionUtility.cs" />
<Compile Include="infrastructure\adapters\IEncryptionUtility.cs" />
Expand Down
145 changes: 145 additions & 0 deletions src/chocolatey/infrastructure.app/commands/ChocolateyExportCommand.cs
Original file line number Diff line number Diff line change
@@ -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<string> 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 [<options/switches>]
");

"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<PackagesConfigFilePackageSetting>();

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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public ChocolateyConfiguration()
PinCommand = new PinCommandConfiguration();
OutdatedCommand = new OutdatedCommandConfiguration();
Proxy = new ProxyConfiguration();
ExportCommand = new ExportCommandConfiguration();
#if DEBUG
AllowUnofficialBuild = true;
#endif
Expand Down Expand Up @@ -334,6 +335,8 @@ private void append_output(StringBuilder propertyValues, string append)
/// </remarks>
public OutdatedCommandConfiguration OutdatedCommand { get; set; }

public ExportCommandConfiguration ExportCommand { get; set; }

/// <summary>
/// Configuration related specifically to proxies.
/// </summary>
Expand Down Expand Up @@ -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; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ public void RegisterComponents(Container container)
new ChocolateyApiKeyCommand(container.GetInstance<IChocolateyConfigSettingsService>()),
new ChocolateyUnpackSelfCommand(container.GetInstance<IFileSystem>()),
new ChocolateyVersionCommand(container.GetInstance<IChocolateyPackageService>()),
new ChocolateyUpdateCommand(container.GetInstance<IChocolateyPackageService>())
new ChocolateyUpdateCommand(container.GetInstance<IChocolateyPackageService>()),
new ChocolateyExportCommand(container.GetInstance<INugetService>(), container.GetInstance<IFileSystem>(), container.GetInstance<IXmlService>())
};
return list.AsReadOnly();
}, Lifestyle.Singleton);
Expand Down

0 comments on commit dc18d24

Please sign in to comment.