Skip to content

Commit

Permalink
Use argument parsing for 'pack' command like 'new'
Browse files Browse the repository at this point in the history
Resolves feedback on issue chocolatey#1313
  • Loading branch information
heaths committed May 31, 2017
1 parent cb3471c commit 08aedee
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 99 deletions.
2 changes: 0 additions & 2 deletions src/chocolatey.tests.integration/scenarios/PackScenarios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ public override void Context()

Scenario.reset(Configuration);

Configuration.PackCommand.Properties.Add("version", "0.1.0");
Configuration.PackCommand.Properties.Add("commitId", "1234abcd");
Scenario.add_files(new[] { new Tuple<string, string>("myPackage.nuspec", NuspecContentWithVariables) });

Expand Down Expand Up @@ -158,7 +157,6 @@ public void property_settings_should_be_logged_as_debug_messages()
{
var messages = MockLogger.MessagesFor(LogLevel.Debug);
messages.Count.ShouldEqual(2);
messages.Contains("Overriding property 'version': 0.1.0");
messages.Contains("Setting property 'commitId': 1234abcd");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,6 @@ public void should_add_outputdirectory_to_the_option_set()
{
optionSet.Contains("outputdirectory").ShouldBeTrue();
}

[Fact]
public void should_add_properties_to_the_option_set()
{
optionSet.Contains("properties").ShouldBeTrue();
}
}

public class when_handling_additional_argument_parsing : ChocolateyPackCommandSpecsBase
Expand All @@ -100,6 +94,11 @@ public override void Context()
{
base.Context();
unparsedArgs.Add(nuspecPath);
unparsedArgs.Add("foo=1");
unparsedArgs.Add("bar='baz'");

// Make sure we storing only the first property name specified regardless of case.
unparsedArgs.Add("Foo=2");
}

public override void Because()
Expand All @@ -112,6 +111,26 @@ public void should_allow_a_path_to_the_nuspec_to_be_passed_in()
{
configuration.Input.ShouldEqual(nuspecPath);
}

[Fact]
public void should_property_foo_equal_1()
{
configuration.PackCommand.Properties["foo"].ShouldEqual("1");
}

[Fact]
public void should_property_bar_equal_baz()
{
configuration.PackCommand.Properties["bar"].ShouldEqual("baz");
}

[Fact]
public void should_log_warning_on_duplicate_foo()
{
var warnings = MockLogger.MessagesFor(LogLevel.Warn);
warnings.Count.ShouldEqual(1);
warnings[0].ShouldEqual("A value for 'foo' has already been added with the value '1'. Ignoring foo='2'.", StringComparer.OrdinalIgnoreCase);
}
}

public class when_noop_is_called : ChocolateyPackCommandSpecsBase
Expand Down Expand Up @@ -155,7 +174,7 @@ public override void Context()

public override void Because()
{
optionSet.Parse(new[] { "--version", "0.42.0", "--outputdirectory", "c:\\packages", "--properties", "foo=1;bar='baz'" });
optionSet.Parse(new[] { "--version", "0.42.0", "--outputdirectory", "c:\\packages" });
}

[Fact]
Expand All @@ -169,58 +188,6 @@ public void should_outputdirectory_equal_packages()
{
configuration.OutputDirectory.ShouldEqual("c:\\packages");
}

[Fact]
public void should_properties_contain_foo()
{
configuration.PackCommand.Properties.ShouldContain(new KeyValuePair<string, string>("foo", "1"));
}

[Fact]
public void should_properties_contain_bar()
{
configuration.PackCommand.Properties.ShouldContain(new KeyValuePair<string, string>("bar", "baz"));
}
}

public class when_handling_arguments_parsing_properties_error : ChocolateyPackCommandSpecsBase
{
private OptionSet optionSet;
private Action because;

public override void Context()
{
base.Context();
optionSet = new OptionSet();
command.configure_argument_parser(optionSet, configuration);
}

public override void Because()
{
because = () => optionSet.Parse(new[] { "--properties", "foo" });
}

[Fact]
public void should_throw_on_ill_formed_property()
{
var errored = false;
Exception error = null;

try
{
because();
}
catch (Exception ex)
{
errored = true;
error = ex;
}

errored.ShouldBeTrue();
error.ShouldNotBeNull();
error.ShouldBeType<ArgumentException>();
error.Message.ShouldContain("Ill-formed name=value pair in token: foo");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public virtual void handle_additional_argument_parsing(IList<string> unparsedArg
{
configuration.NewCommand.Name = unparsedArguments.DefaultIfEmpty(string.Empty).FirstOrDefault(arg => !arg.StartsWith("-") && !arg.contains("="));
var property = unparsedArguments.DefaultIfEmpty(string.Empty).FirstOrDefault().Split(new[] {'='}, StringSplitOptions.RemoveEmptyEntries);
if (property.Count() == 1)
if (property.Length == 1)
{
configuration.NewCommand.TemplateProperties.Add(TemplateValues.NamePropertyName, configuration.NewCommand.Name);
}
Expand All @@ -86,7 +86,7 @@ public virtual void handle_additional_argument_parsing(IList<string> unparsedArg
foreach (var unparsedArgument in unparsedArguments.or_empty_list_if_null())
{
var property = unparsedArgument.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries);
if (property.Count() == 2)
if (property.Length == 2)
{
var propName = property[0].trim_safe();
var propValue = property[1].trim_safe().remove_surrounding_quotes();
Expand Down
55 changes: 28 additions & 27 deletions src/chocolatey/infrastructure.app/commands/ChocolateyPackCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@

namespace chocolatey.infrastructure.app.commands
{
using System;
using System.Collections.Generic;
using System.Linq;
using attributes;
using commandline;
using configuration;
using infrastructure.commands;
using logging;
using services;
using System;

[CommandFor("pack", "packages up a nuspec to a compiled nupkg")]
public class ChocolateyPackCommand : ICommand
Expand All @@ -44,15 +45,32 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon
.Add("out=|outdir=|outputdirectory=|output-directory=",
"OutputDirectory - Specifies the directory for the created Chocolatey package file. If not specified, uses the current directory.",
option => configuration.OutputDirectory = option)
.Add("properties=",
"Properties - A semicolon-delimited list of name=value pairs that will replace $name$ with value in a nuspec.",
option => parse_properties(option, configuration.PackCommand.Properties))
;
}

public virtual void handle_additional_argument_parsing(IList<string> unparsedArguments, ChocolateyConfiguration configuration)
{
configuration.Input = string.Join(" ", unparsedArguments);
// First non-switch argument that is not a name=value pair will be treated as the nuspec file to pack.
configuration.Input = unparsedArguments.DefaultIfEmpty(string.Empty).FirstOrDefault(arg => !arg.StartsWith("-") && !arg.contains("="));

foreach (var unparsedArgument in unparsedArguments.or_empty_list_if_null())
{
var property = unparsedArgument.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries);
if (property.Length == 2)
{
var propName = property[0].trim_safe();
var propValue = property[1].trim_safe().remove_surrounding_quotes();

if (configuration.PackCommand.Properties.ContainsKey(propName))
{
this.Log().Warn(() => "A value for '{0}' has already been added with the value '{1}'. Ignoring {0}='{2}'.".format_with(propName, configuration.PackCommand.Properties[propName], propValue));
}
else
{
configuration.PackCommand.Properties.Add(propName, propValue);
}
}
}
}

public virtual void handle_validation(ChocolateyConfiguration configuration)
Expand All @@ -71,21 +89,24 @@ with options and switches. In most cases you can still pass options
and switches with one dash (`-`). For more details, see
the command reference (`choco -?`).
NOTE: You can pass arbitrary property value pairs through to nuspecs.
These will replace variables formatted as `$property$` with the value passed.
NOTE: `cpack` has been deprecated as it has a name collision with CMake. Please
use `choco pack` instead. The shortcut will be removed in v1.
");

"chocolatey".Log().Info(ChocolateyLoggers.Important, "Usage");
"chocolatey".Log().Info(@"
choco pack [<path to nuspec>] [<options/switches>]
choco pack [<path to nuspec>] [<options/switches>] [<property=value>]
cpack [<path to nuspec>] [<options/switches>] (DEPRECATED)
");

"chocolatey".Log().Info(ChocolateyLoggers.Important, "Examples");
"chocolatey".Log().Info(@"
choco pack
choco pack --version 1.2.3
choco pack --version 1.2.3 configuration=release
choco pack path/to/nuspec
choco pack --outputdirectory build
Expand All @@ -108,25 +129,5 @@ public virtual bool may_require_admin_access()
{
return false;
}

private void parse_properties(string input, IDictionary<string, string> properties)
{
input = input.remove_surrounding_quotes();
if (string.IsNullOrWhiteSpace(input)) return;

var tokens = input.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var token in tokens)
{
var pair = token.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries);
if (pair.Length != 2)
{
throw new ArgumentException(
string.Format("Ill-formed name=value pair in token: {0}", token),
"properties");
}

properties.Add(pair[0], pair[1].remove_surrounding_quotes());
}
}
}
}
19 changes: 10 additions & 9 deletions src/chocolatey/infrastructure.app/services/NugetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,28 +257,29 @@ public string validate_and_return_package_file(ChocolateyConfiguration config, s

public void pack_run(ChocolateyConfiguration config)
{
string nuspecFilePath = validate_and_return_package_file(config, Constants.ManifestExtension);
var nuspecFilePath = validate_and_return_package_file(config, Constants.ManifestExtension);
var nuspecDirectory = _fileSystem.get_full_path(_fileSystem.get_directory_name(nuspecFilePath));
if (string.IsNullOrWhiteSpace(nuspecDirectory)) nuspecDirectory = _fileSystem.get_current_directory();

IDictionary<string, string> properties = new Dictionary<string, string>();
// Set the version property if the flag is set
if (!string.IsNullOrWhiteSpace(config.Version))
{
properties["version"] = config.Version;
}
// Use case-insensitive properties like "nuget pack".
var properties = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

// Add any other properties passed to the pack command overriding any present.
foreach (var property in config.PackCommand.Properties)
{
this.Log().Debug(() => "{0} property '{1}': {2}".format_with(
properties.ContainsKey(property.Key) ? "Overriding" : "Setting",
this.Log().Debug(() => "Setting property '{0}': {1}".format_with(
property.Key,
property.Value));

properties[property.Key] = property.Value;
}

// Set the version property if the flag is set
if (!string.IsNullOrWhiteSpace(config.Version))
{
properties["version"] = config.Version;
}

// Initialize the property provider based on what was passed in using the properties flag
var propertyProvider = new DictionaryPropertyProvider(properties);

Expand Down

0 comments on commit 08aedee

Please sign in to comment.