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.
71 lines
2.4 KiB
C#
71 lines
2.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
|
|
namespace CliFx.Binding;
|
|
|
|
/// <summary>
|
|
/// Describes a binding between a CLR type and a command.
|
|
/// </summary>
|
|
public class CommandDescriptor(
|
|
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
|
Type type,
|
|
string? name,
|
|
string? description,
|
|
IReadOnlyList<string> examples,
|
|
IReadOnlyList<CommandInputDescriptor> inputs
|
|
)
|
|
{
|
|
/// <summary>
|
|
/// CLR type of the command.
|
|
/// </summary>
|
|
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
|
public Type Type { get; } = type;
|
|
|
|
/// <inheritdoc cref="CommandAttribute.Name" />
|
|
public string? Name { get; } = name;
|
|
|
|
internal bool IsDefault => string.IsNullOrWhiteSpace(Name);
|
|
|
|
/// <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>
|
|
public IReadOnlyList<CommandInputDescriptor> Inputs { get; } = inputs;
|
|
|
|
internal IReadOnlyList<CommandParameterDescriptor> Parameters { get; } =
|
|
inputs.OfType<CommandParameterDescriptor>().ToArray();
|
|
|
|
internal IReadOnlyList<CommandOptionDescriptor> Options { get; } =
|
|
inputs.OfType<CommandOptionDescriptor>().ToArray();
|
|
|
|
internal bool MatchesName(string? name) =>
|
|
!string.IsNullOrWhiteSpace(Name)
|
|
? string.Equals(name, Name, StringComparison.OrdinalIgnoreCase)
|
|
: string.IsNullOrWhiteSpace(name);
|
|
|
|
/// <inheritdoc />
|
|
public override string ToString() => !string.IsNullOrWhiteSpace(Name) ? Name : "<default>";
|
|
}
|
|
|
|
/// <inheritdoc cref="CommandDescriptor" />
|
|
/// <remarks>
|
|
/// Generic version used by source-generated code for static type references and AOT compatibility.
|
|
/// </remarks>
|
|
public class CommandDescriptor<
|
|
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
|
TCommand
|
|
>(
|
|
string? name,
|
|
string? description,
|
|
IReadOnlyList<string> examples,
|
|
IReadOnlyList<CommandInputDescriptor> inputs
|
|
) : CommandDescriptor(typeof(TCommand), name, description, examples, inputs)
|
|
where TCommand : ICommand;
|