Skip to content

Commit

Permalink
(chocolateyGH-1313) Allow properties to be passed to 'pack'
Browse files Browse the repository at this point in the history
Passes properties through to the nuget pack command to replace variables
in the nuspec file.
  • Loading branch information
heaths committed Jul 6, 2017
1 parent 237de6a commit 9da1a11
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 8 deletions.
7 changes: 6 additions & 1 deletion Scenarios.md
Original file line number Diff line number Diff line change
Expand Up @@ -473,13 +473,18 @@
* should contain tags
* should not contain packages and versions with a pipe between them

### ChocolateyPackCommand [ 2 Scenario(s), 4 Observation(s) ]
### ChocolateyPackCommand [ 3 Scenario(s), 6 Observation(s) ]

#### when packing with an output directory

* generated package should be in specified output directory
* sources should be set to specified output directory

#### when packing with properties

* generated package should be in current directory
* property settings should be logged as debug messages

#### when packing without specifying an output directory

* generated package should be in current directory
Expand Down
66 changes: 66 additions & 0 deletions src/chocolatey.tests.integration/scenarios/PackScenarios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,54 @@ public void sources_should_be_set_to_specified_output_directory()
}
}

[Concern(typeof(ChocolateyPackCommand))]
public class when_packing_with_properties : ScenariosBase
{
private readonly string package_path = Path.Combine(Scenario.get_top_level(), "test-package.0.1.0.nupkg");

public override void Context()
{
base.Context();

Scenario.reset(Configuration);

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

if (File.Exists(package_path))
{
File.Delete(package_path);
}
}

public override void Because()
{
MockLogger.reset();
Service.pack_run(Configuration);
}

[Fact]
public void generated_package_should_be_in_current_directory()
{
var infos = MockLogger.MessagesFor(LogLevel.Info);
infos.Count.ShouldEqual(2);
infos[0].ShouldEqual("Attempting to build package from 'myPackage.nuspec'.");
infos[1].ShouldEqual(string.Concat("Successfully created package '", package_path, "'"));

File.Exists(package_path).ShouldBeTrue();
}

[Fact]
public void property_settings_should_be_logged_as_debug_messages()
{
var messages = MockLogger.MessagesFor(LogLevel.Debug);
messages.Count.ShouldEqual(2);
messages.Contains("Setting property 'commitId': 1234abcd");
messages.Contains("Setting property 'version': 0.1.0");
}
}

private const string NuspecContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
<package xmlns=""http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"">
<metadata>
Expand All @@ -132,5 +180,23 @@ public void sources_should_be_set_to_specified_output_directory()
<releaseNotes></releaseNotes>
</metadata>
</package>";

private const string NuspecContentWithVariables = @"<?xml version=""1.0"" encoding=""utf-8""?>
<package xmlns=""http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"">
<metadata>
<id>test-package</id>
<title>Test Package</title>
<version>$version$</version>
<authors>package author</authors>
<owners>package owner</owners>
<summary>A brief summary</summary>
<description>A big description</description>
<tags>test admin</tags>
<copyright></copyright>
<licenseUrl>https://github.com/chocolatey/choco/tree/$commitId$/LICENSE</licenseUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<releaseNotes></releaseNotes>
</metadata>
</package>";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace chocolatey.tests.infrastructure.app.commands
using chocolatey.infrastructure.commandline;
using Moq;
using Should;
using System;

public class ChocolateyPackCommandSpecs
{
Expand Down Expand Up @@ -93,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 @@ -105,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
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

namespace chocolatey.infrastructure.app.commands
{
using System;
using System.Collections.Generic;
using System.Linq;
using attributes;
using commandline;
using configuration;
Expand Down Expand Up @@ -48,7 +50,27 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon

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 @@ -67,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 Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public ChocolateyConfiguration()
FeatureCommand = new FeatureCommandConfiguration();
ConfigCommand = new ConfigCommandConfiguration();
ApiKeyCommand = new ApiKeyCommandConfiguration();
PackCommand = new PackCommandConfiguration();
PushCommand = new PushCommandConfiguration();
PinCommand = new PinCommandConfiguration();
OutdatedCommand = new OutdatedCommandConfiguration();
Expand Down Expand Up @@ -300,6 +301,14 @@ private void append_output(StringBuilder propertyValues, string append)
/// </remarks>
public ApiKeyCommandConfiguration ApiKeyCommand { get; set; }

/// <summary>
/// Configuration related specifically to the Pack command.
/// </summary>
/// <remarks>
/// On .NET 4.0, get error CS0200 when private set - see http://stackoverflow.com/a/23809226/18475
/// </remarks>
public PackCommandConfiguration PackCommand { get; set; }

/// <summary>
/// Configuration related specifically to Push command
/// </summary>
Expand Down Expand Up @@ -496,6 +505,17 @@ public sealed class ApiKeyCommandConfiguration
public string Key { get; set; }
}

[Serializable]
public sealed class PackCommandConfiguration
{
public PackCommandConfiguration()
{
Properties = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}

public IDictionary<string, string> Properties { get; private set; }
}

[Serializable]
public sealed class PushCommandConfiguration
{
Expand Down
19 changes: 17 additions & 2 deletions src/chocolatey/infrastructure.app/services/NugetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +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>();
// 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(() => "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))
{
this.Log().Debug(() => "Setting property 'version': {0}".format_with(
config.Version));

properties["version"] = config.Version;
}

Expand Down

0 comments on commit 9da1a11

Please sign in to comment.