Skip to content

Commit 1e15ab1

Browse files
adamsitnikKeboo
andauthored
introduce Command.Parse(CommandLineConfiguration) (#2062)
* remove Argument.Parse as it has side effects: creating RootCommand and setting it as a Parent of given Argument * remove Option.Parse as it has side effects: creating RootCommand and setting it as a Parent of given Option * Move CommandExtensions.Parse to Command.Parse to make it easier to discover * make Parser static * move all extension methods from CommandLineBuilderExtensions to CommandLineBuilder itself, make it partial class to reduce diff size * remove ParseResultExtensions.HasOption, as ParseResult.FindResultFor has all we need * move ParseResultExtensions.Invoke* to ParseResult * move CommandLineConfigurationExtensions to CommandLineConfiguration * Apply suggestions from code review --------- Co-authored-by: Kevin B <[email protected]>
1 parent 2f15c7e commit 1e15ab1

File tree

69 files changed

+1008
-1295
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1008
-1295
lines changed

src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ System.CommandLine
88
public System.Type ValueType { get; }
99
public System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem> GetCompletions(System.CommandLine.Completions.CompletionContext context)
1010
public System.Object GetDefaultValue()
11-
public ParseResult Parse(System.String commandLine)
12-
public ParseResult Parse(System.String[] args)
1311
public System.String ToString()
1412
public class Argument<T> : Argument, IValueDescriptor<T>, System.CommandLine.Binding.IValueDescriptor
1513
.ctor()
@@ -56,44 +54,48 @@ System.CommandLine
5654
public System.Void Add(Symbol symbol)
5755
public System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem> GetCompletions(System.CommandLine.Completions.CompletionContext context)
5856
public System.Collections.Generic.IEnumerator<Symbol> GetEnumerator()
57+
public ParseResult Parse(System.Collections.Generic.IReadOnlyList<System.String> args, CommandLineConfiguration configuration = null)
58+
public ParseResult Parse(System.String commandLine, CommandLineConfiguration configuration = null)
5959
public static class CommandExtensions
6060
public static System.Int32 Invoke(this Command command, System.String[] args, IConsole console = null)
6161
public static System.Int32 Invoke(this Command command, System.String commandLine, IConsole console = null)
6262
public static System.Threading.Tasks.Task<System.Int32> InvokeAsync(this Command command, System.String[] args, IConsole console = null, System.Threading.CancellationToken cancellationToken = null)
6363
public static System.Threading.Tasks.Task<System.Int32> InvokeAsync(this Command command, System.String commandLine, IConsole console = null, System.Threading.CancellationToken cancellationToken = null)
64-
public static ParseResult Parse(this Command command, System.String[] args)
65-
public static ParseResult Parse(this Command command, System.String commandLine)
6664
public class CommandLineBuilder
67-
.ctor(Command rootCommand = null)
65+
.ctor(Command rootCommand)
6866
public Command Command { get; }
69-
public System.CommandLine.Parsing.Parser Build()
70-
public static class CommandLineBuilderExtensions
71-
public static CommandLineBuilder AddMiddleware(this CommandLineBuilder builder, System.CommandLine.Invocation.InvocationMiddleware middleware, System.CommandLine.Invocation.MiddlewareOrder order = Default)
72-
public static CommandLineBuilder AddMiddleware(this CommandLineBuilder builder, System.Action<System.CommandLine.Invocation.InvocationContext> onInvoke, System.CommandLine.Invocation.MiddlewareOrder order = Default)
73-
public static CommandLineBuilder CancelOnProcessTermination(this CommandLineBuilder builder, System.Nullable<System.TimeSpan> timeout = null)
74-
public static CommandLineBuilder EnableDirectives(this CommandLineBuilder builder, System.Boolean value = True)
75-
public static CommandLineBuilder EnablePosixBundling(this CommandLineBuilder builder, System.Boolean value = True)
76-
public static CommandLineBuilder RegisterWithDotnetSuggest(this CommandLineBuilder builder)
77-
public static CommandLineBuilder UseDefaults(this CommandLineBuilder builder)
78-
public static CommandLineBuilder UseEnvironmentVariableDirective(this CommandLineBuilder builder)
79-
public static CommandLineBuilder UseExceptionHandler(this CommandLineBuilder builder, System.Action<System.Exception,System.CommandLine.Invocation.InvocationContext> onException = null, System.Nullable<System.Int32> errorExitCode = null)
80-
public static CommandLineBuilder UseHelp(this CommandLineBuilder builder, System.Nullable<System.Int32> maxWidth = null)
81-
public static CommandLineBuilder UseHelp(this CommandLineBuilder builder, System.String[] helpAliases)
82-
public static CommandLineBuilder UseHelp(this CommandLineBuilder builder, System.Action<System.CommandLine.Help.HelpContext> customize, System.Nullable<System.Int32> maxWidth = null)
83-
public static TBuilder UseHelpBuilder<TBuilder>(this TBuilder builder, System.Func<System.CommandLine.Binding.BindingContext,System.CommandLine.Help.HelpBuilder> getHelpBuilder)
84-
public static CommandLineBuilder UseParseDirective(this CommandLineBuilder builder, System.Int32 errorExitCode = 1)
85-
public static CommandLineBuilder UseParseErrorReporting(this CommandLineBuilder builder, System.Int32 errorExitCode = 1)
86-
public static CommandLineBuilder UseSuggestDirective(this CommandLineBuilder builder)
87-
public static CommandLineBuilder UseTokenReplacer(this CommandLineBuilder builder, System.CommandLine.Parsing.TryReplaceToken replaceToken)
88-
public static CommandLineBuilder UseTypoCorrections(this CommandLineBuilder builder, System.Int32 maxLevenshteinDistance = 3)
89-
public static CommandLineBuilder UseVersionOption(this CommandLineBuilder builder)
90-
public static CommandLineBuilder UseVersionOption(this CommandLineBuilder builder, System.String[] aliases)
67+
public CommandLineBuilder AddMiddleware(System.CommandLine.Invocation.InvocationMiddleware middleware, System.CommandLine.Invocation.MiddlewareOrder order = Default)
68+
public CommandLineBuilder AddMiddleware(System.Action<System.CommandLine.Invocation.InvocationContext> onInvoke, System.CommandLine.Invocation.MiddlewareOrder order = Default)
69+
public CommandLineConfiguration Build()
70+
public CommandLineBuilder CancelOnProcessTermination(System.Nullable<System.TimeSpan> timeout = null)
71+
public CommandLineBuilder EnableDirectives(System.Boolean value = True)
72+
public CommandLineBuilder EnablePosixBundling(System.Boolean value = True)
73+
public CommandLineBuilder RegisterWithDotnetSuggest()
74+
public CommandLineBuilder UseDefaults()
75+
public CommandLineBuilder UseEnvironmentVariableDirective()
76+
public CommandLineBuilder UseExceptionHandler(System.Action<System.Exception,System.CommandLine.Invocation.InvocationContext> onException = null, System.Nullable<System.Int32> errorExitCode = null)
77+
public CommandLineBuilder UseHelp(System.Nullable<System.Int32> maxWidth = null)
78+
public CommandLineBuilder UseHelp(System.String[] helpAliases)
79+
public CommandLineBuilder UseHelp(System.Action<System.CommandLine.Help.HelpContext> customize, System.Nullable<System.Int32> maxWidth = null)
80+
public CommandLineBuilder UseHelpBuilder(System.Func<System.CommandLine.Binding.BindingContext,System.CommandLine.Help.HelpBuilder> getHelpBuilder)
81+
public CommandLineBuilder UseParseDirective(System.Int32 errorExitCode = 1)
82+
public CommandLineBuilder UseParseErrorReporting(System.Int32 errorExitCode = 1)
83+
public CommandLineBuilder UseSuggestDirective()
84+
public CommandLineBuilder UseTokenReplacer(System.CommandLine.Parsing.TryReplaceToken replaceToken)
85+
public CommandLineBuilder UseTypoCorrections(System.Int32 maxLevenshteinDistance = 3)
86+
public CommandLineBuilder UseVersionOption()
87+
public CommandLineBuilder UseVersionOption(System.String[] aliases)
9188
public class CommandLineConfiguration
89+
public static CommandLineBuilder CreateBuilder(Command rootCommand)
9290
.ctor(Command command, System.Boolean enablePosixBundling = True, System.Boolean enableDirectives = True, System.Boolean enableTokenReplacement = True, System.Collections.Generic.IReadOnlyList<System.CommandLine.Invocation.InvocationMiddleware> middlewarePipeline = null, System.Func<System.CommandLine.Binding.BindingContext,System.CommandLine.Help.HelpBuilder> helpBuilderFactory = null, System.CommandLine.Parsing.TryReplaceToken tokenReplacer = null)
9391
public System.Boolean EnableDirectives { get; }
9492
public System.Boolean EnablePosixBundling { get; }
9593
public System.Boolean EnableTokenReplacement { get; }
9694
public Command RootCommand { get; }
95+
public System.Int32 Invoke(System.String commandLine, IConsole console = null)
96+
public System.Int32 Invoke(System.String[] args, IConsole console = null)
97+
public System.Threading.Tasks.Task<System.Int32> InvokeAsync(System.String commandLine, IConsole console = null, System.Threading.CancellationToken cancellationToken = null)
98+
public System.Threading.Tasks.Task<System.Int32> InvokeAsync(System.String[] args, IConsole console = null, System.Threading.CancellationToken cancellationToken = null)
9799
public System.Void ThrowIfInvalid()
98100
public class CommandLineConfigurationException : System.Exception, System.Runtime.Serialization.ISerializable
99101
.ctor(System.String message)
@@ -149,8 +151,6 @@ System.CommandLine
149151
public System.Collections.Generic.List<System.Action<System.CommandLine.Parsing.OptionResult>> Validators { get; }
150152
public System.Type ValueType { get; }
151153
public System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem> GetCompletions(System.CommandLine.Completions.CompletionContext context)
152-
public ParseResult Parse(System.String commandLine)
153-
public ParseResult Parse(System.String[] args)
154154
public class Option<T> : Option, IValueDescriptor<T>, System.CommandLine.Binding.IValueDescriptor
155155
.ctor(System.String name, System.String description = null)
156156
.ctor(System.String[] aliases, System.String description = null)
@@ -170,9 +170,9 @@ System.CommandLine
170170
public static Option<T> AcceptExistingOnly<T>(this Option<T> option)
171171
public class ParseResult
172172
public System.CommandLine.Parsing.CommandResult CommandResult { get; }
173+
public CommandLineConfiguration Configuration { get; }
173174
public System.Collections.Generic.IReadOnlyDictionary<System.String,System.Collections.Generic.IReadOnlyList<System.String>> Directives { get; }
174175
public System.Collections.Generic.IReadOnlyList<System.CommandLine.Parsing.ParseError> Errors { get; }
175-
public System.CommandLine.Parsing.Parser Parser { get; }
176176
public System.CommandLine.Parsing.CommandResult RootCommandResult { get; }
177177
public System.Collections.Generic.IReadOnlyList<System.CommandLine.Parsing.Token> Tokens { get; }
178178
public System.Collections.Generic.IReadOnlyList<System.String> UnmatchedTokens { get; }
@@ -184,6 +184,8 @@ System.CommandLine
184184
public System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem> GetCompletions(System.Nullable<System.Int32> position = null)
185185
public T GetValue<T>(Argument<T> argument)
186186
public T GetValue<T>(Option<T> option)
187+
public System.Int32 Invoke(IConsole console = null)
188+
public System.Threading.Tasks.Task<System.Int32> InvokeAsync(IConsole console = null, System.Threading.CancellationToken cancellationToken = null)
187189
public System.String ToString()
188190
public class RootCommand : Command, System.Collections.Generic.IEnumerable<Symbol>, System.Collections.IEnumerable
189191
public static System.String ExecutableName { get; }
@@ -286,7 +288,6 @@ System.CommandLine.Invocation
286288
public System.Int32 ExitCode { get; set; }
287289
public System.CommandLine.Help.HelpBuilder HelpBuilder { get; }
288290
public System.Action<InvocationContext> InvocationResult { get; set; }
289-
public System.CommandLine.Parsing.Parser Parser { get; }
290291
public System.CommandLine.ParseResult ParseResult { get; set; }
291292
public T GetValue<T>(Option<T> option)
292293
public T GetValue<T>(Argument<T> argument)
@@ -359,22 +360,11 @@ System.CommandLine.Parsing
359360
public System.String Message { get; }
360361
public SymbolResult SymbolResult { get; }
361362
public System.String ToString()
362-
public class Parser
363-
.ctor(System.CommandLine.CommandLineConfiguration configuration)
364-
.ctor(System.CommandLine.Command command)
365-
public System.CommandLine.CommandLineConfiguration Configuration { get; }
366-
public System.CommandLine.ParseResult Parse(System.Collections.Generic.IReadOnlyList<System.String> arguments, System.String rawInput = null)
363+
public static class Parser
364+
public static System.CommandLine.ParseResult Parse(System.CommandLine.Command command, System.Collections.Generic.IReadOnlyList<System.String> args, System.CommandLine.CommandLineConfiguration configuration = null)
365+
public static System.CommandLine.ParseResult Parse(System.CommandLine.Command command, System.String commandLine, System.CommandLine.CommandLineConfiguration configuration = null)
367366
public static class ParseResultExtensions
368367
public static System.String Diagram(this System.CommandLine.ParseResult parseResult)
369-
public static System.Boolean HasOption(this System.CommandLine.ParseResult parseResult, System.CommandLine.Option option)
370-
public static System.Int32 Invoke(this System.CommandLine.ParseResult parseResult, System.CommandLine.IConsole console = null)
371-
public static System.Threading.Tasks.Task<System.Int32> InvokeAsync(this System.CommandLine.ParseResult parseResult, System.CommandLine.IConsole console = null, System.Threading.CancellationToken cancellationToken = null)
372-
public static class ParserExtensions
373-
public static System.Int32 Invoke(this Parser parser, System.String commandLine, System.CommandLine.IConsole console = null)
374-
public static System.Int32 Invoke(this Parser parser, System.String[] args, System.CommandLine.IConsole console = null)
375-
public static System.Threading.Tasks.Task<System.Int32> InvokeAsync(this Parser parser, System.String commandLine, System.CommandLine.IConsole console = null, System.Threading.CancellationToken cancellationToken = null)
376-
public static System.Threading.Tasks.Task<System.Int32> InvokeAsync(this Parser parser, System.String[] args, System.CommandLine.IConsole console = null, System.Threading.CancellationToken cancellationToken = null)
377-
public static System.CommandLine.ParseResult Parse(this Parser parser, System.String commandLine)
378368
public abstract class SymbolResult
379369
public SymbolResult Parent { get; }
380370
public System.Collections.Generic.IReadOnlyList<Token> Tokens { get; }

src/System.CommandLine.Benchmarks/CommandLine/Perf_Parser_CustomScenarios.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,24 @@ namespace System.CommandLine.Benchmarks.CommandLine
1313
public class Perf_Parser_CustomScenarios
1414
{
1515
private string _testSymbolsAsString;
16-
private Parser _testParser;
16+
private Command _rootCommand;
17+
private CommandLineConfiguration _configuration;
1718

1819
[GlobalSetup(Target = nameof(OneOptWithNestedCommand_Parse))]
1920
public void SetupOneOptWithNestedCommand()
2021
{
21-
var rootCommand = new Command("root_command");
22+
_rootCommand = new Command("root_command");
2223
var nestedCommand = new Command("nested_command");
2324
var option = new Option<int>("-opt1", () => 123);
2425
nestedCommand.Options.Add(option);
25-
rootCommand.Subcommands.Add(nestedCommand);
26+
_rootCommand.Subcommands.Add(nestedCommand);
2627

27-
_testParser = new Parser(rootCommand);
2828
_testSymbolsAsString = "root_command nested_command -opt1 321";
29+
_configuration = CommandLineConfiguration.CreateBuilder(_rootCommand).UseDefaults().Build();
2930
}
3031

3132
[Benchmark]
3233
public ParseResult OneOptWithNestedCommand_Parse()
33-
=> _testParser.Parse(_testSymbolsAsString);
34+
=> _rootCommand.Parse(_testSymbolsAsString, _configuration);
3435
}
3536
}

src/System.CommandLine.Benchmarks/CommandLine/Perf_Parser_Directives_Suggest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace System.CommandLine.Benchmarks.CommandLine
1515
public class Perf_Parser_Directives_Suggest
1616
{
1717
private NullConsole _nullConsole;
18-
private Parser _testParser;
18+
private CommandLineConfiguration _configuration;
1919

2020
[GlobalSetup]
2121
public void Setup()
@@ -34,7 +34,7 @@ public void Setup()
3434
vegetableOption
3535
};
3636

37-
_testParser = new CommandLineBuilder(eatCommand)
37+
_configuration = new CommandLineBuilder(eatCommand)
3838
.UseSuggestDirective()
3939
.Build();
4040
}
@@ -47,7 +47,7 @@ public void Setup()
4747

4848
[Benchmark]
4949
public Task InvokeSuggest()
50-
=> _testParser.InvokeAsync(TestCmdArgs, _nullConsole);
50+
=> _configuration.InvokeAsync(TestCmdArgs, _nullConsole);
5151

5252
}
5353
}

src/System.CommandLine.Benchmarks/CommandLine/Perf_Parser_NestedCommands.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ namespace System.CommandLine.Benchmarks.CommandLine
1313
public class Perf_Parser_NestedCommands
1414
{
1515
private string _testSymbolsAsString;
16-
private Parser _testParser;
1716
private Command _rootCommand;
17+
private CommandLineConfiguration _configuration;
1818

1919
/// <remarks>
2020
/// 1 - cmd-root
@@ -45,7 +45,7 @@ private void GenerateTestNestedCommands(Command parent, int depth, int countPerL
4545
}
4646
}
4747

48-
[GlobalSetup(Target = nameof(ParserFromNestedCommands_Ctor))]
48+
[GlobalSetup]
4949
public void SetupRootCommand()
5050
{
5151
string rootCommandName = "root";
@@ -62,19 +62,10 @@ public void SetupRootCommand()
6262
}
6363

6464
_rootCommand = rootCommand;
65+
_configuration = CommandLineConfiguration.CreateBuilder(rootCommand).UseDefaults().Build();
6566
}
6667

67-
[GlobalSetup(Target = nameof(Parser_Parse))]
68-
public void SetupParser()
69-
{
70-
SetupRootCommand();
71-
_testParser = new Parser(_rootCommand);
72-
}
73-
74-
[Benchmark]
75-
public Parser ParserFromNestedCommands_Ctor() => new(_rootCommand);
76-
7768
[Benchmark]
78-
public ParseResult Parser_Parse() => _testParser.Parse(_testSymbolsAsString);
69+
public ParseResult Parser_Parse() => Parser.Parse(_rootCommand, _testSymbolsAsString, _configuration);
7970
}
8071
}

src/System.CommandLine.Benchmarks/CommandLine/Perf_Parser_Options_Bare.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class Perf_Parser_Options_Bare
1717
{
1818
private IEnumerable<Option> _testSymbols;
1919
private string _testSymbolsAsString;
20-
private Parser _testParser;
20+
private CommandLineConfiguration _testConfiguration;
2121

2222
private IEnumerable<Option> GenerateTestOptions(int count, ArgumentArity arity)
2323
=> Enumerable.Range(0, count)
@@ -49,20 +49,20 @@ public void SetupTestOptions()
4949
}
5050

5151
[Benchmark]
52-
public Parser ParserFromOptions_Ctor()
52+
public CommandLineConfiguration ParserFromOptions_Ctor()
5353
{
54-
return _testSymbols.CreateParser();
54+
return _testSymbols.CreateConfiguration();
5555
}
5656

5757
[GlobalSetup(Target = nameof(ParserFromOptions_Parse))]
5858
public void SetupParserFromOptions_Parse()
5959
{
6060
var testSymbolsArr = GenerateTestOptions(TestSymbolsCount, ArgumentArity.Zero).ToArray();
61-
_testParser = testSymbolsArr.CreateParser();
61+
_testConfiguration = testSymbolsArr.CreateConfiguration();
6262
_testSymbolsAsString = GenerateTestOptionsAsStringExpr(testSymbolsArr.Length);
6363
}
6464

6565
[Benchmark]
66-
public ParseResult ParserFromOptions_Parse() => _testParser.Parse(_testSymbolsAsString);
66+
public ParseResult ParserFromOptions_Parse() => _testConfiguration.RootCommand.Parse(_testSymbolsAsString, _testConfiguration);
6767
}
6868
}

src/System.CommandLine.Benchmarks/CommandLine/Perf_Parser_Options_With_Arguments.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace System.CommandLine.Benchmarks.CommandLine
1616
public class Perf_Parser_Options_With_Arguments
1717
{
1818
private string _testSymbolsAsString;
19-
private Parser _testParser;
19+
private CommandLineConfiguration _configuration;
2020

2121
private IEnumerable<Option> GenerateTestOptions(int count, ArgumentArity arity)
2222
=> Enumerable.Range(0, count)
@@ -54,11 +54,11 @@ private string GenerateTestOptionsWithArgumentsAsStringExpr(int optionsCount, in
5454
public void SetupParserFromOptionsWithArguments_Parse()
5555
{
5656
var testSymbolsArr = GenerateTestOptions(TestOptionsCount, ArgumentArity.OneOrMore).ToArray();
57-
_testParser = testSymbolsArr.CreateParser();
57+
_configuration = testSymbolsArr.CreateConfiguration();
5858
_testSymbolsAsString = GenerateTestOptionsWithArgumentsAsStringExpr(testSymbolsArr.Length, TestArgumentsCount);
5959
}
6060

6161
[Benchmark]
62-
public ParseResult ParserFromOptionsWithArguments_Parse() => _testParser.Parse(_testSymbolsAsString);
62+
public ParseResult ParserFromOptionsWithArguments_Parse() => _configuration.RootCommand.Parse(_testSymbolsAsString, _configuration);
6363
}
6464
}

0 commit comments

Comments
 (0)