Como personalizar a ajuda em aplicativos criados com a biblioteca System.Commandline

Você pode personalizar a ajuda para um comando, opção ou argumento específico e pode adicionar ou substituir seções de ajuda inteiras.

Os exemplos neste artigo funcionam com o seguinte aplicativo de linha de comando:

Este código requer uma using diretiva:

using System.CommandLine;
var fileOption = new Option<FileInfo>(
    "--file",
    description: "The file to print out.",
    getDefaultValue: () => new FileInfo("scl.runtimeconfig.json"));
var lightModeOption = new Option<bool> (
    "--light-mode",
    description: "Determines whether the background color will be black or white");
var foregroundColorOption = new Option<ConsoleColor>(
    "--color",
    description: "Specifies the foreground color of console output",
    getDefaultValue: () => ConsoleColor.White);

var rootCommand = new RootCommand("Read a file")
{
    fileOption,
    lightModeOption,
    foregroundColorOption
};

rootCommand.SetHandler((file, lightMode, color) =>
    {
        Console.BackgroundColor = lightMode ? ConsoleColor.White: ConsoleColor.Black;
        Console.ForegroundColor = color;
        Console.WriteLine($"--file = {file?.FullName}");
        Console.WriteLine($"File contents:\n{file?.OpenText().ReadToEnd()}");
    },
    fileOption,
    lightModeOption,
    foregroundColorOption);

await rootCommand.InvokeAsync(args);

Sem personalização, a seguinte saída de ajuda é produzida:

Description:
  Read a file

Usage:
  scl [options]

Options:
  --file <file>                                               The file to print out. [default: scl.runtimeconfig.json]
  --light-mode                                                Determines whether the background color will be black or
                                                              white
  --color                                                     Specifies the foreground color of console output
  <Black|Blue|Cyan|DarkBlue|DarkCyan|DarkGray|DarkGreen|Dark  [default: White]
  Magenta|DarkRed|DarkYellow|Gray|Green|Magenta|Red|White|Ye
  llow>
  --version                                                   Show version information
  -?, -h, --help                                              Show help and usage information

Personalizar a ajuda para uma única opção ou argumento

Importante

System.CommandLine está atualmente em PREVIEW, e esta documentação é para a versão 2.0 beta 4. Algumas informações estão relacionadas ao produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.

Para personalizar o nome do argumento de uma opção, use a propriedade da ArgumentHelpName opção. E HelpBuilder.CustomizeSymbol permite personalizar várias partes da saída de ajuda para um comando, opção ou argumento (Symbol é a classe base para todos os três tipos). Com CustomizeSymbolo , você pode especificar:

  • O texto da primeira coluna.
  • O texto da segunda coluna.
  • A maneira como um valor padrão é descrito.

No aplicativo de exemplo, --light-mode é explicado adequadamente, mas as alterações nas descrições e --file--color opções serão úteis. Para --file, o argumento pode ser identificado como um <FILEPATH> em vez de <file>. Para a --color opção, você pode encurtar a lista de cores disponíveis na coluna um e, na coluna dois, pode adicionar um aviso de que algumas cores não funcionarão com alguns planos de fundo.

Para fazer essas alterações, exclua a await rootCommand.InvokeAsync(args); linha mostrada no código anterior e adicione em seu lugar o seguinte código:

fileOption.ArgumentHelpName = "FILEPATH";

var parser = new CommandLineBuilder(rootCommand)
        .UseDefaults()
        .UseHelp(ctx =>
        {
            ctx.HelpBuilder.CustomizeSymbol(foregroundColorOption,
                firstColumnText: "--color <Black, White, Red, or Yellow>",
                secondColumnText: "Specifies the foreground color. " +
                    "Choose a color that provides enough contrast " +
                    "with the background color. " + 
                    "For example, a yellow foreground can't be read " +
                    "against a light mode background.");
        })
        .Build();

parser.Invoke(args);

O código atualizado requer diretivas adicionais using :

using System.CommandLine.Builder;
using System.CommandLine.Help;
using System.CommandLine.Parsing;

O aplicativo agora produz a seguinte saída de ajuda:

Description:
  Read a file

Usage:
  scl [options]

Options:
  --file <FILEPATH>                       The file to print out. [default: CustomHelp.runtimeconfig.json]
  --light-mode                            Determines whether the background color will be black or white
  --color <Black, White, Red, or Yellow>  Specifies the foreground color. Choose a color that provides enough contrast
                                          with the background color. For example, a yellow foreground can't be read
                                          against a light mode background.
  --version                               Show version information
  -?, -h, --help                          Show help and usage information

Esta saída mostra que os firstColumnText parâmetros e secondColumnText suportam quebra automática de palavras dentro de suas colunas.

Adicionar ou substituir secções de ajuda

Você pode adicionar ou substituir uma seção inteira da saída de ajuda. Por exemplo, suponha que você queira adicionar alguma arte ASCII à seção de descrição usando o pacote NuGet do Spectre.Console .

Altere o layout adicionando uma chamada para HelpBuilder.CustomizeLayout no lambda passado para o UseHelp método:

fileOption.ArgumentHelpName = "FILEPATH";

var parser = new CommandLineBuilder(rootCommand)
        .UseDefaults()
        .UseHelp(ctx =>
        {
            ctx.HelpBuilder.CustomizeSymbol(foregroundColorOption,
                firstColumnText: "--color <Black, White, Red, or Yellow>",
                secondColumnText: "Specifies the foreground color. " +
                    "Choose a color that provides enough contrast " +
                    "with the background color. " +
                    "For example, a yellow foreground can't be read " +
                    "against a light mode background.");
            ctx.HelpBuilder.CustomizeLayout(
                _ =>
                    HelpBuilder.Default
                        .GetLayout()
                        .Skip(1) // Skip the default command description section.
                        .Prepend(
                            _ => Spectre.Console.AnsiConsole.Write(
                                new FigletText(rootCommand.Description!))
                ));
        })
        .Build();

await parser.InvokeAsync(args);

O código anterior exige uma diretiva adicional using :

using Spectre.Console;

A System.CommandLine.Help.HelpBuilder.Default classe permite reutilizar partes da funcionalidade de formatação de ajuda existente e compô-las em sua ajuda personalizada.

A saída da ajuda agora tem esta aparência:

  ____                       _                __   _   _
 |  _ \    ___    __ _    __| |     __ _     / _| (_) | |   ___
 | |_) |  / _ \  / _` |  / _` |    / _` |   | |_  | | | |  / _ \
 |  _ <  |  __/ | (_| | | (_| |   | (_| |   |  _| | | | | |  __/
 |_| \_\  \___|  \__,_|  \__,_|    \__,_|   |_|   |_| |_|  \___|


Usage:
  scl [options]

Options:
  --file <FILEPATH>                       The file to print out. [default: CustomHelp.runtimeconfig.json]
  --light-mode                            Determines whether the background color will be black or white
  --color <Black, White, Red, or Yellow>  Specifies the foreground color. Choose a color that provides enough contrast
                                          with the background color. For example, a yellow foreground can't be read
                                          against a light mode background.
  --version                               Show version information
  -?, -h, --help                          Show help and usage information

Se você quiser apenas usar uma cadeia de caracteres como o texto da seção de substituição em vez de formatá-lo com Spectre.Console, substitua o Prepend código no exemplo anterior pelo seguinte código:

.Prepend(
    _ => _.Output.WriteLine("**New command description section**")

Consulte também

System.CommandLine Visão geral