feat: add command usage examples
Add an Examples string array property to CommandAttribute so command authors can document example invocations. Each example contains only the arguments that follow the command name; the executable and command name are prepended automatically when the example is rendered. Examples are rendered as extra lines in the USAGE section of the help text. The source generator resolves the values from the attribute and emits them into the command descriptor consumed at runtime.
This commit is contained in:
1 parent
50964082ba
commit
5e1eff9f24
6 files changed
+133
-3
No files matched your search
@@ -29,4 +29,15 @@ public class CommandAttribute(string? name) : Attribute
|
||||
/// Used for display purposes in the help text.
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Usage examples of the command.
|
||||
/// Used for display purposes in the help text.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Each example should only contain the parameters and options that come after the
|
||||
/// command name; the command name itself is prepended automatically when the example
|
||||
/// is rendered in the help text.
|
||||
/// </remarks>
|
||||
public string[] Examples { get; set; } = [];
|
||||
}
|
||||
@@ -13,6 +13,7 @@ public class CommandDescriptor(
|
||||
Type type,
|
||||
string? name,
|
||||
string? description,
|
||||
IReadOnlyList<string> examples,
|
||||
IReadOnlyList<CommandInputDescriptor> inputs
|
||||
)
|
||||
{
|
||||
@@ -30,6 +31,9 @@ public class CommandDescriptor(
|
||||
/// <inheritdoc cref="CommandAttribute.Description" />
|
||||
public string? Description { get; } = description;
|
||||
|
||||
/// <inheritdoc cref="CommandAttribute.Examples" />
|
||||
public IReadOnlyList<string> Examples { get; } = examples;
|
||||
|
||||
/// <summary>
|
||||
/// Inputs (parameters and options) of the command;
|
||||
/// </summary>
|
||||
@@ -57,6 +61,10 @@ public class CommandDescriptor(
|
||||
public class CommandDescriptor<
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
||||
TCommand
|
||||
>(string? name, string? description, IReadOnlyList<CommandInputDescriptor> inputs)
|
||||
: CommandDescriptor(typeof(TCommand), name, description, inputs)
|
||||
>(
|
||||
string? name,
|
||||
string? description,
|
||||
IReadOnlyList<string> examples,
|
||||
IReadOnlyList<CommandInputDescriptor> inputs
|
||||
) : CommandDescriptor(typeof(TCommand), name, description, examples, inputs)
|
||||
where TCommand : ICommand;
|
||||
@@ -73,6 +73,19 @@ internal class HelpWriter(HelpContext context, ConsoleWriter consoleWriter)
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
// Examples
|
||||
foreach (var example in context.Command.Examples)
|
||||
{
|
||||
WriteHorizontalMargin();
|
||||
|
||||
WriteCommandInvocation();
|
||||
Write(' ');
|
||||
|
||||
Write(example);
|
||||
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
// Child commands
|
||||
if (context.Root.GetChildCommands(context.Command.Name).Any())
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user