Skip to content

Commit dd44dd0

Browse files
authored
Fix #1665 (#1714)
* remove `ResponseFileHandling` enum and `TokenizeError` class * remove a number of public setters / getters on `CommandLineBuilder` for tokenizer-level settings * introduce `CommandLineBuilder.UseTokenReplacer` API * generalize token replacement, implement response files as the default
1 parent 3fef055 commit dd44dd0

14 files changed

+416
-227
lines changed

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

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,11 @@
7171
public static System.CommandLine.Parsing.ParseResult Parse(this Command command, System.String[] args)
7272
public static System.CommandLine.Parsing.ParseResult Parse(this Command command, System.String commandLine)
7373
public class CommandLineConfiguration
74-
.ctor(Command command, System.Boolean enablePosixBundling = True, System.Boolean enableDirectives = True, System.Boolean enableLegacyDoubleDashBehavior = False, LocalizationResources resources = null, System.CommandLine.Parsing.ResponseFileHandling responseFileHandling = ParseArgsAsLineSeparated, System.Collections.Generic.IReadOnlyList<System.CommandLine.Invocation.InvocationMiddleware> middlewarePipeline = null, System.Func<System.CommandLine.Binding.BindingContext,System.CommandLine.Help.HelpBuilder> helpBuilderFactory = null)
74+
.ctor(Command command, System.Boolean enablePosixBundling = True, System.Boolean enableDirectives = True, System.Boolean enableLegacyDoubleDashBehavior = False, System.Boolean enableTokenReplacement = True, LocalizationResources resources = null, 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)
7575
public System.Boolean EnableDirectives { get; }
7676
public System.Boolean EnableLegacyDoubleDashBehavior { get; }
7777
public System.Boolean EnablePosixBundling { get; }
78+
public System.Boolean EnableTokenReplacement { get; }
7879
public LocalizationResources LocalizationResources { get; }
7980
public Command RootCommand { get; }
8081
public System.Void ThrowIfInvalid()
@@ -250,10 +251,6 @@ System.CommandLine.Builder
250251
public class CommandLineBuilder
251252
.ctor(System.CommandLine.Command rootCommand = null)
252253
public System.CommandLine.Command Command { get; }
253-
public System.Boolean EnableDirectives { get; set; }
254-
public System.Boolean EnableLegacyDoubleDashBehavior { get; set; }
255-
public System.Boolean EnablePosixBundling { get; set; }
256-
public System.CommandLine.Parsing.ResponseFileHandling ResponseFileHandling { get; set; }
257254
public System.CommandLine.Parsing.Parser Build()
258255
public static class CommandLineBuilderExtensions
259256
public static CommandLineBuilder AddMiddleware(this CommandLineBuilder builder, System.CommandLine.Invocation.InvocationMiddleware middleware, System.CommandLine.Invocation.MiddlewareOrder order = Default)
@@ -262,7 +259,6 @@ System.CommandLine.Builder
262259
public static CommandLineBuilder EnableDirectives(this CommandLineBuilder builder, System.Boolean value = True)
263260
public static CommandLineBuilder EnableLegacyDoubleDashBehavior(this CommandLineBuilder builder, System.Boolean value = True)
264261
public static CommandLineBuilder EnablePosixBundling(this CommandLineBuilder builder, System.Boolean value = True)
265-
public static CommandLineBuilder ParseResponseFileAs(this CommandLineBuilder builder, System.CommandLine.Parsing.ResponseFileHandling responseFileHandling)
266262
public static CommandLineBuilder RegisterWithDotnetSuggest(this CommandLineBuilder builder)
267263
public static CommandLineBuilder UseDefaults(this CommandLineBuilder builder)
268264
public static CommandLineBuilder UseEnvironmentVariableDirective(this CommandLineBuilder builder)
@@ -275,6 +271,7 @@ System.CommandLine.Builder
275271
public static CommandLineBuilder UseParseDirective(this CommandLineBuilder builder, System.Nullable<System.Int32> errorExitCode = null)
276272
public static CommandLineBuilder UseParseErrorReporting(this CommandLineBuilder builder, System.Nullable<System.Int32> errorExitCode = null)
277273
public static CommandLineBuilder UseSuggestDirective(this CommandLineBuilder builder)
274+
public static CommandLineBuilder UseTokenReplacer(this CommandLineBuilder builder, System.CommandLine.Parsing.TryReplaceToken replaceToken)
278275
public static CommandLineBuilder UseTypoCorrections(this CommandLineBuilder builder, System.Int32 maxLevenshteinDistance = 3)
279276
public static CommandLineBuilder UseVersionOption(this CommandLineBuilder builder)
280277
public static CommandLineBuilder UseVersionOption(this CommandLineBuilder builder, System.String[] aliases)
@@ -476,10 +473,6 @@ System.CommandLine.Parsing
476473
public static System.Threading.Tasks.Task<System.Int32> InvokeAsync(this Parser parser, System.String commandLine, System.CommandLine.IConsole console = null)
477474
public static System.Threading.Tasks.Task<System.Int32> InvokeAsync(this Parser parser, System.String[] args, System.CommandLine.IConsole console = null)
478475
public static ParseResult Parse(this Parser parser, System.String commandLine)
479-
public enum ResponseFileHandling : System.Enum, System.IComparable, System.IConvertible, System.IFormattable
480-
ParseArgsAsLineSeparated=0
481-
ParseArgsAsSpaceSeparated=1
482-
Disabled=2
483476
public abstract class SymbolResult
484477
public System.Collections.Generic.IReadOnlyList<SymbolResult> Children { get; }
485478
public System.String ErrorMessage { get; set; }
@@ -505,16 +498,18 @@ System.CommandLine.Parsing
505498
public System.Boolean Equals(Token other)
506499
public System.Int32 GetHashCode()
507500
public System.String ToString()
508-
public class TokenizeError
509-
public System.String Message { get; }
510-
public System.String ToString()
511501
public enum TokenType : System.Enum, System.IComparable, System.IConvertible, System.IFormattable
512502
Argument=0
513503
Command=1
514504
Option=2
515505
DoubleDash=3
516506
Unparsed=4
517507
Directive=5
508+
public delegate TryReplaceToken : System.MulticastDelegate, System.ICloneable, System.Runtime.Serialization.ISerializable
509+
.ctor(System.Object object, System.IntPtr method)
510+
public System.IAsyncResult BeginInvoke(System.String tokenToReplace, ref System.Collections.Generic.IReadOnlyList<System.String> replacementTokens, ref System.String& errorMessage, System.AsyncCallback callback, System.Object object)
511+
public System.Boolean EndInvoke(ref System.Collections.Generic.IReadOnlyList<System.String> replacementTokens, ref System.String& errorMessage, System.IAsyncResult result)
512+
public System.Boolean Invoke(System.String tokenToReplace, ref System.Collections.Generic.IReadOnlyList<System.String> replacementTokens, ref System.String& errorMessage)
518513
public delegate ValidateSymbolResult<in T> : System.MulticastDelegate, System.ICloneable, System.Runtime.Serialization.ISerializable
519514
.ctor(System.Object object, System.IntPtr method)
520515
public System.IAsyncResult BeginInvoke(T symbolResult, System.AsyncCallback callback, System.Object object)

src/System.CommandLine.Tests/ResponseFileTests.cs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public void Dispose()
2424
}
2525
}
2626

27-
private string ResponseFile(params string[] lines)
27+
private string CreateResponseFile(params string[] lines)
2828
{
2929
var responseFile = new FileInfo(Path.GetTempFileName());
3030

@@ -46,15 +46,15 @@ public void When_response_file_specified_it_loads_options_from_response_file()
4646
{
4747
var option = new Option<bool>("--flag");
4848

49-
var result = option.Parse($"@{ResponseFile("--flag")}");
49+
var result = option.Parse($"@{CreateResponseFile("--flag")}");
5050

5151
result.HasOption(option).Should().BeTrue();
5252
}
5353

5454
[Fact]
5555
public void When_response_file_is_specified_it_loads_options_with_arguments_from_response_file()
5656
{
57-
var responseFile = ResponseFile(
57+
var responseFile = CreateResponseFile(
5858
"--flag",
5959
"--flag2",
6060
"123");
@@ -77,7 +77,7 @@ public void When_response_file_is_specified_it_loads_options_with_arguments_from
7777
[Fact]
7878
public void When_response_file_is_specified_it_loads_command_arguments_from_response_file()
7979
{
80-
var responseFile = ResponseFile(
80+
var responseFile = CreateResponseFile(
8181
"one",
8282
"two",
8383
"three");
@@ -98,7 +98,7 @@ public void When_response_file_is_specified_it_loads_command_arguments_from_resp
9898
[Fact]
9999
public void Response_file_can_provide_subcommand_arguments()
100100
{
101-
var responseFile = ResponseFile(
101+
var responseFile = CreateResponseFile(
102102
"one",
103103
"two",
104104
"three");
@@ -122,7 +122,7 @@ public void Response_file_can_provide_subcommand_arguments()
122122
[Fact]
123123
public void Response_file_can_provide_subcommand()
124124
{
125-
var responseFile = ResponseFile("subcommand");
125+
var responseFile = CreateResponseFile("subcommand");
126126

127127
var result = new RootCommand
128128
{
@@ -143,7 +143,7 @@ public void Response_file_can_provide_subcommand()
143143
[Fact]
144144
public void When_response_file_is_specified_it_loads_subcommand_arguments_from_response_file()
145145
{
146-
var responseFile = ResponseFile(
146+
var responseFile = CreateResponseFile(
147147
"one",
148148
"two",
149149
"three");
@@ -167,7 +167,7 @@ public void When_response_file_is_specified_it_loads_subcommand_arguments_from_r
167167
[Fact]
168168
public void Response_file_can_contain_blank_lines()
169169
{
170-
var responseFile = ResponseFile(
170+
var responseFile = CreateResponseFile(
171171
"--flag",
172172
"",
173173
"123");
@@ -190,7 +190,7 @@ public void Response_file_can_contain_comments_which_are_ignored_when_loaded()
190190
var optionOne = new Option<bool>("--flag");
191191
var optionTwo = new Option<bool>("--flag2");
192192

193-
var responseFile = ResponseFile(
193+
var responseFile = CreateResponseFile(
194194
"# comment one",
195195
"--flag",
196196
"# comment two",
@@ -278,7 +278,7 @@ public void When_response_file_cannot_be_read_then_specified_error_is_returned()
278278
[InlineData("--flag=\"first value\" --flag2=123")]
279279
public void When_response_file_parse_as_space_separated_returns_expected_values(string input)
280280
{
281-
var responseFile = ResponseFile(input);
281+
var responseFile = CreateResponseFile(input);
282282

283283
var optionOne = new Option<string>("--flag");
284284
var optionTwo = new Option<int>("--flag2");
@@ -289,7 +289,6 @@ public void When_response_file_parse_as_space_separated_returns_expected_values(
289289
optionTwo
290290
};
291291
var parser = new CommandLineBuilder(rootCommand)
292-
.ParseResponseFileAs(ResponseFileHandling.ParseArgsAsSpaceSeparated)
293292
.Build();
294293

295294
var result = parser.Parse($"@{responseFile}");
@@ -307,7 +306,8 @@ public void When_response_file_processing_is_disabled_then_it_returns_response_f
307306
};
308307
var configuration = new CommandLineConfiguration(
309308
command,
310-
responseFileHandling: ResponseFileHandling.Disabled);
309+
enableTokenReplacement: false);
310+
311311
var parser = new Parser(configuration);
312312

313313
var result = parser.Parse("@file.rsp");
@@ -322,9 +322,9 @@ public void When_response_file_processing_is_disabled_then_it_returns_response_f
322322
[Fact]
323323
public void Response_files_can_refer_to_other_response_files()
324324
{
325-
var file3 = ResponseFile("--three", "3");
326-
var file2 = ResponseFile($"@{file3}", "--two", "2");
327-
var file1 = ResponseFile("--one", "1", $"@{file2}");
325+
var file3 = CreateResponseFile("--three", "3");
326+
var file2 = CreateResponseFile($"@{file3}", "--two", "2");
327+
var file1 = CreateResponseFile("--one", "1", $"@{file2}");
328328

329329
var option1 = new Option<int>("--one");
330330
var option2 = new Option<int>("--two");
@@ -339,17 +339,17 @@ public void Response_files_can_refer_to_other_response_files()
339339

340340
var result = command.Parse($"@{file1}");
341341

342-
result.FindResultFor(option1).GetValueOrDefault().Should().Be(1);
343-
result.FindResultFor(option1).GetValueOrDefault().Should().Be(1);
344-
result.FindResultFor(option2).GetValueOrDefault().Should().Be(2);
345-
result.FindResultFor(option3).GetValueOrDefault().Should().Be(3);
342+
result.GetValueForOption(option1).Should().Be(1);
343+
result.GetValueForOption(option1).Should().Be(1);
344+
result.GetValueForOption(option2).Should().Be(2);
345+
result.GetValueForOption(option3).Should().Be(3);
346346
result.Errors.Should().BeEmpty();
347347
}
348348

349349
[Fact]
350350
public void When_response_file_options_or_arguments_contain_trailing_spaces_they_are_ignored()
351351
{
352-
var responseFile = ResponseFile("--option1 ", "value1 ", "--option2\t", "2\t");
352+
var responseFile = CreateResponseFile("--option1 ", "value1 ", "--option2\t", "2\t");
353353

354354
var option1 = new Option<string>("--option1");
355355
var option2 = new Option<int>("--option2");
@@ -362,7 +362,7 @@ public void When_response_file_options_or_arguments_contain_trailing_spaces_they
362362
[Fact]
363363
public void When_response_file_options_or_arguments_contain_leading_spaces_they_are_ignored()
364364
{
365-
var responseFile = ResponseFile(" --option1", " value1", "\t--option2", "\t2");
365+
var responseFile = CreateResponseFile(" --option1", " value1", "\t--option2", "\t2");
366366

367367
var option1 = new Option<string>("--option1");
368368
var option2 = new Option<int>("--option2");
@@ -376,7 +376,7 @@ public void When_response_file_options_or_arguments_contain_leading_spaces_they_
376376
[Fact]
377377
public void When_response_file_options_or_arguments_contain_trailing_and_leading_spaces_they_are_ignored()
378378
{
379-
var responseFile = ResponseFile(" --option1 ", " value1 ", "\t--option2\t", "\t2\t");
379+
var responseFile = CreateResponseFile(" --option1 ", " value1 ", "\t--option2\t", "\t2\t");
380380

381381
var option1 = new Option<string>("--option1");
382382
var option2 = new Option<int>("--option2");

0 commit comments

Comments
 (0)