mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-14 16:02:50 +08:00
Expose raw arguments on the command context
This commit is contained in:
parent
de04619f88
commit
95bff47b85
@ -13,6 +13,11 @@ public sealed class CommandContext
|
||||
/// </value>
|
||||
public IRemainingArguments Remaining { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the arguments that were passed to the applicaton.
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Arguments { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the command.
|
||||
/// </summary>
|
||||
@ -32,11 +37,17 @@ public sealed class CommandContext
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CommandContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="arguments">All arguments that were passed to the application.</param>
|
||||
/// <param name="remaining">The remaining arguments.</param>
|
||||
/// <param name="name">The command name.</param>
|
||||
/// <param name="data">The command data.</param>
|
||||
public CommandContext(IRemainingArguments remaining, string name, object? data)
|
||||
public CommandContext(
|
||||
IEnumerable<string> arguments,
|
||||
IRemainingArguments remaining,
|
||||
string name,
|
||||
object? data)
|
||||
{
|
||||
Arguments = arguments.ToSafeReadOnlyList();
|
||||
Remaining = remaining ?? throw new System.ArgumentNullException(nameof(remaining));
|
||||
Name = name ?? throw new System.ArgumentNullException(nameof(name));
|
||||
Data = data;
|
||||
|
@ -12,6 +12,7 @@ public interface IRemainingArguments
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw, non-parsed remaining arguments.
|
||||
/// This is normally everything after the `--` delimiter.
|
||||
/// </summary>
|
||||
IReadOnlyList<string> Raw { get; }
|
||||
}
|
@ -17,7 +17,7 @@ internal sealed class CommandExecutor
|
||||
throw new ArgumentNullException(nameof(configuration));
|
||||
}
|
||||
|
||||
args ??= new List<string>();
|
||||
var arguments = args.ToSafeReadOnlyList();
|
||||
|
||||
_registrar.RegisterInstance(typeof(IConfiguration), configuration);
|
||||
_registrar.RegisterLazy(typeof(IAnsiConsole), () => configuration.Settings.Console.GetConsole());
|
||||
@ -31,7 +31,7 @@ internal sealed class CommandExecutor
|
||||
if (model.DefaultCommand == null)
|
||||
{
|
||||
// Got at least one argument?
|
||||
var firstArgument = args.FirstOrDefault();
|
||||
var firstArgument = arguments.FirstOrDefault();
|
||||
if (firstArgument != null)
|
||||
{
|
||||
// Asking for version? Kind of a hack, but it's alright.
|
||||
@ -47,7 +47,7 @@ internal sealed class CommandExecutor
|
||||
}
|
||||
|
||||
// Parse and map the model against the arguments.
|
||||
var parsedResult = ParseCommandLineArguments(model, configuration.Settings, args);
|
||||
var parsedResult = ParseCommandLineArguments(model, configuration.Settings, arguments);
|
||||
|
||||
// Register the arguments with the container.
|
||||
_registrar.RegisterInstance(typeof(CommandTreeParserResult), parsedResult);
|
||||
@ -79,7 +79,7 @@ internal sealed class CommandExecutor
|
||||
}
|
||||
|
||||
// Is this the default and is it called without arguments when there are required arguments?
|
||||
if (leaf.Command.IsDefaultCommand && args.Count() == 0 && leaf.Command.Parameters.Any(p => p.Required))
|
||||
if (leaf.Command.IsDefaultCommand && arguments.Count == 0 && leaf.Command.Parameters.Any(p => p.Required))
|
||||
{
|
||||
// Display help for default command.
|
||||
configuration.Settings.Console.SafeRender(helpProvider.Write(model, leaf.Command));
|
||||
@ -87,15 +87,18 @@ internal sealed class CommandExecutor
|
||||
}
|
||||
|
||||
// Create the content.
|
||||
var context = new CommandContext(parsedResult.Remaining, leaf.Command.Name, leaf.Command.Data);
|
||||
var context = new CommandContext(
|
||||
arguments,
|
||||
parsedResult.Remaining,
|
||||
leaf.Command.Name,
|
||||
leaf.Command.Data);
|
||||
|
||||
// Execute the command tree.
|
||||
return await Execute(leaf, parsedResult.Tree, context, resolver, configuration).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable CS8603 // Possible null reference return.
|
||||
private CommandTreeParserResult ParseCommandLineArguments(CommandModel model, CommandAppSettings settings, IEnumerable<string> args)
|
||||
private CommandTreeParserResult ParseCommandLineArguments(CommandModel model, CommandAppSettings settings, IReadOnlyList<string> args)
|
||||
{
|
||||
var parser = new CommandTreeParser(model, settings.CaseSensitivity, settings.ParsingMode, settings.ConvertFlagsToRemainingArguments);
|
||||
|
||||
@ -103,7 +106,7 @@ internal sealed class CommandExecutor
|
||||
var tokenizerResult = CommandTreeTokenizer.Tokenize(args);
|
||||
var parsedResult = parser.Parse(parserContext, tokenizerResult);
|
||||
|
||||
var lastParsedLeaf = parsedResult?.Tree?.GetLeafCommand();
|
||||
var lastParsedLeaf = parsedResult.Tree?.GetLeafCommand();
|
||||
var lastParsedCommand = lastParsedLeaf?.Command;
|
||||
if (lastParsedLeaf != null && lastParsedCommand != null &&
|
||||
lastParsedCommand.IsBranch && !lastParsedLeaf.ShowHelp &&
|
||||
@ -122,7 +125,6 @@ internal sealed class CommandExecutor
|
||||
|
||||
return parsedResult;
|
||||
}
|
||||
#pragma warning restore CS8603 // Possible null reference return.
|
||||
|
||||
private static string ResolveApplicationVersion(IConfiguration configuration)
|
||||
{
|
||||
|
@ -0,0 +1,14 @@
|
||||
namespace Spectre.Console.Cli;
|
||||
|
||||
internal static class EnumerableExtensions
|
||||
{
|
||||
public static IReadOnlyList<T> ToSafeReadOnlyList<T>(this IEnumerable<T> source)
|
||||
{
|
||||
return source switch
|
||||
{
|
||||
null => new List<T>(),
|
||||
IReadOnlyList<T> list => list,
|
||||
_ => source.ToList(),
|
||||
};
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.3" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -0,0 +1,23 @@
|
||||
namespace Spectre.Console.Tests.Unit.Cli;
|
||||
|
||||
public sealed partial class CommandAppTests
|
||||
{
|
||||
[Fact]
|
||||
[Expectation("Should_Expose_Raw_Arguments")]
|
||||
public void Should_Return_Correct_Text_When_Command_Is_Unknown()
|
||||
{
|
||||
// Given
|
||||
var app = new CommandAppTester();
|
||||
app.Configure(config =>
|
||||
{
|
||||
config.AddCommand<EmptyCommand>("test");
|
||||
});
|
||||
|
||||
// When
|
||||
var result = app.Run("test", "--foo", "32", "--lol");
|
||||
|
||||
// Then
|
||||
result.Context.ShouldNotBeNull();
|
||||
result.Context.Arguments.ShouldBe(new[] { "test", "--foo", "32", "--lol" });
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user