5

在蛋糕构建脚本中,有一种非常简洁的方法可以使用任务.Description()上的扩展来记录任务。使用参数调用构建脚本时会显示这些描述-showdescription

我的构建脚本中有几个自定义参数,我想以某种方式记录它们。目前,我添加了一个任务,该任务为可用参数输出类似于手册页样式的描述文本,如下所示:

var nextLineDescription = "\n\t\t\t\t\t"; // for formatting 
Console.WriteLine("ARGUMENTS");
Console.WriteLine("");

Console.WriteLine("\t--someparameter=<number>\t\t" +
                "Description of the parameter" + nextLineDescription +
                "that can span multiple lines" + nextLineDescription +
                "and defaults to 5.\n");

这工作正常,但工作量很大,特别是如果文本应该正确格式化以便在命令行中可读。

所以当我打电话时,./build.ps1 -Target MyDocTask 我得到了一个很好的结果:

论据

        --someparameter=number 参数说明
                                        可以跨越多行
                                        并且默认为 5

        --nextParameter 下一个描述

...

是否有另一种方法或最佳实践来为参数添加文档,以便它可以在类似于任务描述的命令行中显示?

编辑:或者,我可以在我的构建脚本中找到所有可用参数来循环它们并生成这样的描述,而不是为每个参数手动编写它吗?

4

1 回答 1

6

目前没有用于“注册”参数以寻求帮助的内置功能,虽然这将是一个很好的补充,所以请提出一个问题。

也就是说,它可以实现,因为 Cake 只是 .NET,您可以利用 NuGet 上可用的命令行解析器之一来实现这一点。一种这样的解析器是CommandLineParser

可以使用该#addin指令从 NuGet 引用程序集,对于 CommandLineParser 它如下所示

#addin "nuget:?package=CommandLineParser&version=2.1.1-beta&prerelease=true"

由于它不是“本机”Cake 插件,因此您需要使用完全限定的类型名称,或者就像常规 C# 添加这样的 using 语句

using CommandLine;

CommandLineParser 使用类和属性上的属性来提供规则和帮助。在下面移植您的示例将如下所示

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; }
}

通常 CommandLineParser 会向控制台输出帮助,但如果你想在任务中显示它,你可以使用TextWriter

var helpWriter = new StringWriter();
var parser = new Parser(config => config.HelpWriter = helpWriter);

然后解析参数,如果指定了“MyDocTask”,则向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
);

和任务

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);

MyDocTask输出帮助

>> 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.

并且Default任务将只输出解析参数的值

>> cake .\commandline.cake

========================================
Default
========================================
SomeParameter: 5
NextParameter: [NULL]
Target: Default

Task                          Duration
--------------------------------------------------
Default                       00:00:00.0133265
--------------------------------------------------
Total:                        00:00:00.0133265

这将以一种相当简单的方式为您提供强类型和文档化的参数。

完整的 Cake 脚本如下:

#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);
于 2017-07-31T12:42:27.387 回答