Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass an argument that is a string array to my Cake script?

Tags:

cakebuild

I want to get an Argument<IEnumerable<string>> (or string[], or whatever - an iterable list of strings) to my Cake script, but I can't figure out how to pass it from build.ps1 to cake.exe.

This is what I have so far:

In build.ps1:

param(
    # ...
    [ValidateSet("Bar", "Baz")]
    [string[]]$Foo
)

# ...

$fooArg = If ($Foo.Count -gt 0) {"-foo=`(`"{0}`"`)" -f [string]::Join("`",`", $Foo)} Else {""}
Invoke-Expression "$CAKE_EXE ... $fooArg"

In build.cake:

var baz = Argument<IEnumerable<string>>("foo", new string[0]);

However, when I execute this, I get the following error:

More than one build script specified.

Could not find a build script to execute.
Either the first argument must the build script's path,
or build script should follow default script name conventions.

Usage: Cake.exe [build-script] [-verbosity=value] [-showdescription] [-dryrun] [..]

Example: Cake.exe Example: Cake.exe build.cake -verbosity=quiet Example: Cake.exe build.cake -showdescription

Options: -verbosity=value Specifies the amount of information to be displayed. (Quiet, Minimal, Normal, Verbose, Diagnostic) -showdescription Shows description about tasks. -dryrun Performs a dry run. -version Displays version information. -help Displays usage information. -experimental Uses the nightly builds of Roslyn script engine.

What's the correct way to do this?

like image 234
Tomas Aschan Avatar asked Mar 14 '23 02:03

Tomas Aschan


1 Answers

Solution #1 (simple):

You could solve it simply by accepting the argument as a string and split it:

var foo = Argument("foo", string.Empty).Split(',');

Solution #2 (complex):

You could also solve this by wrapping the string array in a custom type and implement a TypeConverter for that type. Both the wrapper and the type converter would have to reside in a .NET assembly that would be loaded either via the #r or #addin directive.

[TypeConverter(typeof(StringArrayConverter))]
public class StringArray
{
    public string[] Items { get; }
}

public class StringArrayConverter : TypeConverter
{
  // Implementation here :)
}

You would then use the Argument alias as usual with the StringArray type.

var foo = Argument<StringArray>("foo", null);

In my opinion, this option is a little bit complex for getting a string array so you might want to go with the simpler solution until we've added IEnumerable support for arguments.

like image 179
Patrik Svensson Avatar answered May 05 '23 06:05

Patrik Svensson