mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-17 17:32:50 +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]
|
myapp <TEETH> [LEGS] [OPTIONS]
|
||||||
|
|
||||||
ARGUMENTS:
|
ARGUMENTS:
|
||||||
[LEGS] The number of legs
|
|
||||||
<TEETH> The number of teeth the lion has
|
<TEETH> The number of teeth the lion has
|
||||||
|
[LEGS] The number of legs
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
-h, --help Prints help information
|
-h, --help Prints help information
|
||||||
|
@ -5,8 +5,8 @@ EXAMPLES:
|
|||||||
myapp 12 -c 3
|
myapp 12 -c 3
|
||||||
|
|
||||||
ARGUMENTS:
|
ARGUMENTS:
|
||||||
[LEGS] The number of legs
|
|
||||||
<TEETH> The number of teeth the lion has
|
<TEETH> The number of teeth the lion has
|
||||||
|
[LEGS] The number of legs
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
-h, --help Prints help information
|
-h, --help Prints help information
|
||||||
|
@ -244,6 +244,24 @@ namespace Spectre.Console.Tests.Unit.Cli
|
|||||||
// Then
|
// Then
|
||||||
return Verifier.Verify(output);
|
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
|
private sealed class HelpArgument
|
||||||
{
|
{
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
public int Position { get; set; }
|
||||||
public bool Required { get; }
|
public bool Required { get; }
|
||||||
public string? Description { 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;
|
Name = name;
|
||||||
|
Position = position;
|
||||||
Required = required;
|
Required = required;
|
||||||
Description = description;
|
Description = description;
|
||||||
}
|
}
|
||||||
@ -25,7 +27,7 @@ namespace Spectre.Console.Cli.Internal
|
|||||||
{
|
{
|
||||||
var arguments = new List<HelpArgument>();
|
var arguments = new List<HelpArgument>();
|
||||||
arguments.AddRange(command?.Parameters?.OfType<CommandArgument>()?.Select(
|
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>());
|
?? Array.Empty<HelpArgument>());
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
@ -94,63 +96,61 @@ namespace Spectre.Console.Cli.Internal
|
|||||||
composer.Style("yellow", "USAGE:").LineBreak();
|
composer.Style("yellow", "USAGE:").LineBreak();
|
||||||
composer.Tab().Text(model.GetApplicationName());
|
composer.Tab().Text(model.GetApplicationName());
|
||||||
|
|
||||||
var parameters = new Stack<string>();
|
var parameters = new List<string>();
|
||||||
|
|
||||||
if (command == null)
|
if (command == null)
|
||||||
{
|
{
|
||||||
parameters.Push("[aqua]<COMMAND>[/]");
|
parameters.Add("[grey][[OPTIONS]][/]");
|
||||||
parameters.Push("[grey][[OPTIONS]][/]");
|
parameters.Add("[aqua]<COMMAND>[/]");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var current = command;
|
foreach (var current in command.Flatten())
|
||||||
if (command.IsBranch)
|
|
||||||
{
|
|
||||||
parameters.Push("[aqua]<COMMAND>[/]");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (current != null)
|
|
||||||
{
|
{
|
||||||
var isCurrent = current == command;
|
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 (!current.IsDefaultCommand)
|
||||||
{
|
{
|
||||||
if (isCurrent)
|
if (isCurrent)
|
||||||
{
|
{
|
||||||
parameters.Push($"[underline]{current.Name.EscapeMarkup()}[/]");
|
parameters.Add($"[underline]{current.Name.EscapeMarkup()}[/]");
|
||||||
}
|
}
|
||||||
else
|
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(4, 4), NoWrap = true });
|
||||||
grid.AddColumn(new GridColumn { Padding = new Padding(0, 0) });
|
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()}>[/]",
|
||||||
grid.AddRow(
|
argument.Description?.TrimEnd('.') ?? " ");
|
||||||
$"[silver]<{argument.Name.EscapeMarkup()}>[/]",
|
}
|
||||||
argument.Description?.TrimEnd('.') ?? " ");
|
|
||||||
}
|
foreach (var argument in arguments.Where(x => !x.Required).OrderBy(x => x.Position))
|
||||||
else
|
{
|
||||||
{
|
grid.AddRow(
|
||||||
grid.AddRow(
|
$"[grey][[{argument.Name.EscapeMarkup()}]][/]",
|
||||||
$"[grey][[{argument.Name.EscapeMarkup()}]][/]",
|
argument.Description?.TrimEnd('.') ?? " ");
|
||||||
argument.Description?.TrimEnd('.') ?? " ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
grid.AddEmptyRow();
|
grid.AddEmptyRow();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace Spectre.Console.Cli.Internal
|
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