There's currently no built-in feature for "registering" arguments for help, would be an great addition though so please raise an issue about that.
That said it can be achieved, as Cake is just .NET you could utilize one of the command line parsers available on NuGet to achieve this. One such parser is CommandLineParser.
Assemblies can be references from NuGet using the #addin
directive, for CommandLineParser it looks below
#addin "nuget:?package=CommandLineParser&version=2.1.1-beta&prerelease=true"
As it's not an "native" Cake addin you'll need to use fully qualified type names or just like regular C# add a using statement like this
using CommandLine;
CommandLineParser uses a class and attributes on the properties to provide rules and help. Porting your example below would look something like below
class Options
{
[Option("someparameter",
HelpText = "Description of the parameter, that can span multiple lines",
Default = 5)]
public int SomeParameter { get; set; }
[Option("nextParameter", HelpText = "Next description")]
public string NextParameter { get; set; }
[Option("target", HelpText = "Target", Default = "Default")]
public string Target { get; set; }
}
Normally CommandLineParser will output help to the console, but if you want to display it in a task, you can capture the output with a TextWriter
var helpWriter = new StringWriter();
var parser = new Parser(config => config.HelpWriter = helpWriter);
Then parsing arguments and if "MyDocTask" is specified render help to the helpWriter
Options options = parser
.ParseArguments<Options>(
StringComparer.OrdinalIgnoreCase.Equals(Argument("target", "Default"), "MyDocTask")
? new []{ "--help" }
: System.Environment.GetCommandLineArgs()
)
.MapResult(
o => o,
errors=> new Options { Target = "MyDocTask"} // TODO capture errors here
);
and tasks
Task("MyDocTask")
.Does(() => {
Information(helpWriter.ToString());
}
);
Task("Default")
.Does(() => {
Information("SomeParameter: {0}", options.SomeParameter);
Information("NextParameter: {0}", options.NextParameter);
Information("Target: {0}", options.Target);
}
);
then executed
RunTarget(options.Target);
The MyDocTask
will output the help
>> cake .\commandline.cake --Target="MyDocTask"
========================================
MyDocTask
========================================
Cake 0.20.0+Branch.main.Sha.417d1eb9097a6c71ab25736687162c0f58bbb74a
Copyright (c) .NET Foundation and Contributors
--someparameter (Default: 5) Description of the parameter, that can span multiple lines
--nextParameter Next description
--target (Default: Default) Target
--help Display this help screen.
--version Display version information.
and Default
task will just output values of the parsed arguments
>> cake .\commandline.cake
========================================
Default
========================================
SomeParameter: 5
NextParameter: [NULL]
Target: Default
Task Duration
--------------------------------------------------
Default 00:00:00.0133265
--------------------------------------------------
Total: 00:00:00.0133265
This will give you strongly typed and documented arguments in a fairly easy way.
The complete Cake script below:
#addin "nuget:?package=CommandLineParser&version=2.1.1-beta&prerelease=true"
using CommandLine;
class Options
{
[Option("someparameter",
HelpText = "Description of the parameter, that can span multiple lines",
Default = 5)]
public int SomeParameter { get; set; }
[Option("nextParameter", HelpText = "Next description")]
public string NextParameter { get; set; }
[Option("target", HelpText = "Target", Default = "Default")]
public string Target { get; set; }
}
var helpWriter = new StringWriter();
var parser = new Parser(config => config.HelpWriter = helpWriter);
Options options = parser
.ParseArguments<Options>(
StringComparer.OrdinalIgnoreCase.Equals(Argument("target", "Default"), "MyDocTask")
? new []{ "--help" }
: System.Environment.GetCommandLineArgs()
)
.MapResult(
o => o,
errors=> new Options { Target = "MyDocTask"} // could capture errors here
);
Task("MyDocTask")
.Does(() => {
Information(helpWriter.ToString());
}
);
Task("Default")
.Does(() => {
Information("SomeParameter: {0}", options.SomeParameter);
Information("NextParameter: {0}", options.NextParameter);
Information("Target: {0}", options.Target);
}
);
RunTarget(options.Target);