mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-16 00:42:51 +08:00
parent
5cf41725a5
commit
b81739567b
@ -0,0 +1,22 @@
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Tests.Data
|
||||
{
|
||||
public sealed class ArgumentOrderSettings : CommandSettings
|
||||
{
|
||||
[CommandArgument(0, "[QUX]")]
|
||||
public int Qux { get; set; }
|
||||
|
||||
[CommandArgument(3, "<CORGI>")]
|
||||
public int Corgi { get; set; }
|
||||
|
||||
[CommandArgument(1, "<BAR>")]
|
||||
public int Bar { get; set; }
|
||||
|
||||
[CommandArgument(2, "<BAZ>")]
|
||||
public int Baz { get; set; }
|
||||
|
||||
[CommandArgument(0, "<FOO>")]
|
||||
public int Foo { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
USAGE:
|
||||
myapp <FOO> <BAR> <BAZ> <CORGI> [QUX] [OPTIONS]
|
||||
|
||||
ARGUMENTS:
|
||||
<FOO>
|
||||
<BAR>
|
||||
<BAZ>
|
||||
<CORGI>
|
||||
[QUX]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Prints help information
|
@ -2,8 +2,8 @@ USAGE:
|
||||
myapp <TEETH> [LEGS] [OPTIONS]
|
||||
|
||||
ARGUMENTS:
|
||||
[LEGS] The number of legs
|
||||
<TEETH> The number of teeth the lion has
|
||||
[LEGS] The number of legs
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Prints help information
|
||||
|
@ -5,8 +5,8 @@ EXAMPLES:
|
||||
myapp 12 -c 3
|
||||
|
||||
ARGUMENTS:
|
||||
[LEGS] The number of legs
|
||||
<TEETH> The number of teeth the lion has
|
||||
[LEGS] The number of legs
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Prints help information
|
||||
|
@ -244,6 +244,24 @@ namespace Spectre.Console.Tests.Unit.Cli
|
||||
// Then
|
||||
return Verifier.Verify(output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task Should_List_Arguments_In_Correct_Order()
|
||||
{
|
||||
// Given
|
||||
var fixture = new CommandAppFixture();
|
||||
fixture.WithDefaultCommand<GenericCommand<ArgumentOrderSettings>>();
|
||||
fixture.Configure(configurator =>
|
||||
{
|
||||
configurator.SetApplicationName("myapp");
|
||||
});
|
||||
|
||||
// When
|
||||
var (_, output, _, _) = fixture.Run("--help");
|
||||
|
||||
// Then
|
||||
return Verifier.Verify(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,12 +11,14 @@ namespace Spectre.Console.Cli.Internal
|
||||
private sealed class HelpArgument
|
||||
{
|
||||
public string Name { get; }
|
||||
public int Position { get; set; }
|
||||
public bool Required { get; }
|
||||
public string? Description { get; }
|
||||
|
||||
public HelpArgument(string name, bool required, string? description)
|
||||
public HelpArgument(string name, int position, bool required, string? description)
|
||||
{
|
||||
Name = name;
|
||||
Position = position;
|
||||
Required = required;
|
||||
Description = description;
|
||||
}
|
||||
@ -25,7 +27,7 @@ namespace Spectre.Console.Cli.Internal
|
||||
{
|
||||
var arguments = new List<HelpArgument>();
|
||||
arguments.AddRange(command?.Parameters?.OfType<CommandArgument>()?.Select(
|
||||
x => new HelpArgument(x.Value, x.Required, x.Description))
|
||||
x => new HelpArgument(x.Value, x.Position, x.Required, x.Description))
|
||||
?? Array.Empty<HelpArgument>());
|
||||
return arguments;
|
||||
}
|
||||
@ -94,63 +96,61 @@ namespace Spectre.Console.Cli.Internal
|
||||
composer.Style("yellow", "USAGE:").LineBreak();
|
||||
composer.Tab().Text(model.GetApplicationName());
|
||||
|
||||
var parameters = new Stack<string>();
|
||||
var parameters = new List<string>();
|
||||
|
||||
if (command == null)
|
||||
{
|
||||
parameters.Push("[aqua]<COMMAND>[/]");
|
||||
parameters.Push("[grey][[OPTIONS]][/]");
|
||||
parameters.Add("[grey][[OPTIONS]][/]");
|
||||
parameters.Add("[aqua]<COMMAND>[/]");
|
||||
}
|
||||
else
|
||||
{
|
||||
var current = command;
|
||||
if (command.IsBranch)
|
||||
{
|
||||
parameters.Push("[aqua]<COMMAND>[/]");
|
||||
}
|
||||
|
||||
while (current != null)
|
||||
foreach (var current in command.Flatten())
|
||||
{
|
||||
var isCurrent = current == command;
|
||||
if (isCurrent)
|
||||
{
|
||||
parameters.Push("[grey][[OPTIONS]][/]");
|
||||
}
|
||||
|
||||
if (current.Parameters.OfType<CommandArgument>().Any())
|
||||
{
|
||||
var optionalArguments = current.Parameters.OfType<CommandArgument>().Where(x => !x.Required).ToArray();
|
||||
if (optionalArguments.Length > 0 || !isCurrent)
|
||||
{
|
||||
foreach (var optionalArgument in optionalArguments)
|
||||
{
|
||||
parameters.Push($"[silver][[{optionalArgument.Value.EscapeMarkup()}]][/]");
|
||||
}
|
||||
}
|
||||
|
||||
if (isCurrent)
|
||||
{
|
||||
foreach (var argument in current.Parameters.OfType<CommandArgument>()
|
||||
.Where(a => a.Required).OrderBy(a => a.Position).ToArray())
|
||||
{
|
||||
parameters.Push($"[aqua]<{argument.Value.EscapeMarkup()}>[/]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!current.IsDefaultCommand)
|
||||
{
|
||||
if (isCurrent)
|
||||
{
|
||||
parameters.Push($"[underline]{current.Name.EscapeMarkup()}[/]");
|
||||
parameters.Add($"[underline]{current.Name.EscapeMarkup()}[/]");
|
||||
}
|
||||
else
|
||||
{
|
||||
parameters.Push($"{current.Name.EscapeMarkup()}");
|
||||
parameters.Add($"{current.Name.EscapeMarkup()}");
|
||||
}
|
||||
}
|
||||
|
||||
current = current.Parent;
|
||||
if (current.Parameters.OfType<CommandArgument>().Any())
|
||||
{
|
||||
if (isCurrent)
|
||||
{
|
||||
foreach (var argument in current.Parameters.OfType<CommandArgument>()
|
||||
.Where(a => a.Required).OrderBy(a => a.Position).ToArray())
|
||||
{
|
||||
parameters.Add($"[aqua]<{argument.Value.EscapeMarkup()}>[/]");
|
||||
}
|
||||
}
|
||||
|
||||
var optionalArguments = current.Parameters.OfType<CommandArgument>().Where(x => !x.Required).ToArray();
|
||||
if (optionalArguments.Length > 0 || !isCurrent)
|
||||
{
|
||||
foreach (var optionalArgument in optionalArguments)
|
||||
{
|
||||
parameters.Add($"[silver][[{optionalArgument.Value.EscapeMarkup()}]][/]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isCurrent)
|
||||
{
|
||||
parameters.Add("[grey][[OPTIONS]][/]");
|
||||
}
|
||||
}
|
||||
|
||||
if (command.IsBranch)
|
||||
{
|
||||
parameters.Add("[aqua]<COMMAND>[/]");
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,20 +238,18 @@ namespace Spectre.Console.Cli.Internal
|
||||
grid.AddColumn(new GridColumn { Padding = new Padding(4, 4), NoWrap = true });
|
||||
grid.AddColumn(new GridColumn { Padding = new Padding(0, 0) });
|
||||
|
||||
foreach (var argument in arguments)
|
||||
foreach (var argument in arguments.Where(x => x.Required).OrderBy(x => x.Position))
|
||||
{
|
||||
if (argument.Required)
|
||||
{
|
||||
grid.AddRow(
|
||||
$"[silver]<{argument.Name.EscapeMarkup()}>[/]",
|
||||
argument.Description?.TrimEnd('.') ?? " ");
|
||||
}
|
||||
else
|
||||
{
|
||||
grid.AddRow(
|
||||
$"[grey][[{argument.Name.EscapeMarkup()}]][/]",
|
||||
argument.Description?.TrimEnd('.') ?? " ");
|
||||
}
|
||||
grid.AddRow(
|
||||
$"[silver]<{argument.Name.EscapeMarkup()}>[/]",
|
||||
argument.Description?.TrimEnd('.') ?? " ");
|
||||
}
|
||||
|
||||
foreach (var argument in arguments.Where(x => !x.Required).OrderBy(x => x.Position))
|
||||
{
|
||||
grid.AddRow(
|
||||
$"[grey][[{argument.Name.EscapeMarkup()}]][/]",
|
||||
argument.Description?.TrimEnd('.') ?? " ");
|
||||
}
|
||||
|
||||
grid.AddEmptyRow();
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Spectre.Console.Cli.Internal
|
||||
@ -51,5 +52,19 @@ namespace Spectre.Console.Cli.Internal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<CommandInfo> Flatten()
|
||||
{
|
||||
var result = new Stack<CommandInfo>();
|
||||
|
||||
var current = this;
|
||||
while (current != null)
|
||||
{
|
||||
result.Push(current);
|
||||
current = current.Parent;
|
||||
}
|
||||
|
||||
return result.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user