Skip to content

Commit 7b3d683

Browse files
authored
Fix #1631 (#1632)
* remove unused RevertFile local function * fix #1631; reorganize double dash behavior tests * cleanup
1 parent d886a77 commit 7b3d683

File tree

5 files changed

+102
-57
lines changed

5 files changed

+102
-57
lines changed

src/System.CommandLine.Tests/ParserTests.DoubleDash.cs

Lines changed: 93 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,95 @@ namespace System.CommandLine.Tests
1111
{
1212
public partial class ParserTests
1313
{
14-
public class DoubleDash
14+
public class DefaultDoubleDashBehavior
1515
{
16+
[Fact] // https://github.com/dotnet/command-line-api/issues/1238
17+
public void Subsequent_tokens_are_parsed_as_arguments_even_if_they_match_option_identifiers()
18+
{
19+
var option = new Option<string[]>(new[] { "-o", "--one" });
20+
var argument = new Argument<string[]>();
21+
var rootCommand = new RootCommand
22+
{
23+
option,
24+
argument
25+
};
26+
27+
var result = new CommandLineBuilder(rootCommand)
28+
.EnableLegacyDoubleDashBehavior(false)
29+
.Build()
30+
.Parse("-o \"some stuff\" -- -o --one -x -y -z -o:foo");
31+
32+
result.HasOption(option).Should().BeTrue();
33+
34+
result.GetValueForOption(option).Should().BeEquivalentTo("some stuff");
35+
36+
result.GetValueForArgument(argument).Should().BeEquivalentSequenceTo("-o", "--one", "-x", "-y", "-z", "-o:foo");
37+
38+
result.UnparsedTokens.Should().BeEmpty();
39+
}
40+
41+
[Fact]
42+
public void Unparsed_tokens_is_empty()
43+
{
44+
var option = new Option<string[]>(new[] { "-o", "--one" });
45+
var argument = new Argument<string[]>();
46+
var rootCommand = new RootCommand
47+
{
48+
option,
49+
argument
50+
};
51+
52+
var result = new CommandLineBuilder(rootCommand)
53+
.EnableLegacyDoubleDashBehavior(false)
54+
.Build()
55+
.Parse("-o \"some stuff\" -- --one -x -y -z -o:foo");
56+
57+
result.UnparsedTokens.Should().BeEmpty();
58+
}
59+
60+
[Fact] // https://github.com/dotnet/command-line-api/issues/1631
61+
public void No_errors_are_generated()
62+
{
63+
var option = new Option<string[]>(new[] { "-o", "--one" });
64+
var argument = new Argument<string[]>();
65+
var rootCommand = new RootCommand
66+
{
67+
option,
68+
argument
69+
};
70+
71+
var result = new CommandLineBuilder(rootCommand)
72+
.EnableLegacyDoubleDashBehavior(false)
73+
.Build()
74+
.Parse("-o \"some stuff\" -- -o --one -x -y -z -o:foo");
75+
76+
result.Errors.Should().BeEmpty();
77+
}
78+
1679
[Fact]
17-
public void When_legacy_behavior_is_enabled_then_the_portion_of_the_command_line_following_a_double_dasare_treated_as_unparsed_tokens()
80+
public void A_second_double_dash_is_parsed_as_an_argument()
81+
{
82+
var argument = new Argument<string[]>();
83+
var rootCommand = new RootCommand
84+
{
85+
argument
86+
};
87+
88+
var result = new CommandLineBuilder(rootCommand)
89+
.EnableLegacyDoubleDashBehavior(false)
90+
.Build()
91+
.Parse("a b c -- -- d");
92+
93+
var strings = result.GetValueForArgument(argument);
94+
95+
strings.Should().BeEquivalentSequenceTo("a", "b", "c", "--", "d");
96+
}
97+
}
98+
99+
public class LegacyDoubleDashBehavior
100+
{
101+
[Fact]
102+
public void The_portion_of_the_command_line_following_a_double_is_treated_as_unparsed_tokens()
18103
{
19104
var result = new CommandLineBuilder(new RootCommand { new Option("-o") })
20105
.EnableLegacyDoubleDashBehavior()
@@ -27,7 +112,7 @@ public void When_legacy_behavior_is_enabled_then_the_portion_of_the_command_line
27112
}
28113

29114
[Fact]
30-
public void When_legacy_behavior_is_enabled_then_a_double_dash_specifies_that_tokens_matching_options_will_be_treated_as_unparsed_tokens()
115+
public void Subsequent_tokens_matching_options_will_be_treated_as_unparsed_tokens()
31116
{
32117
var optionO = new Option(new[] { "-o" });
33118
var optionX = new Option(new[] { "-x" });
@@ -59,47 +144,19 @@ public void When_legacy_behavior_is_enabled_then_a_double_dash_specifies_that_to
59144
}
60145

61146
[Fact]
62-
public void When_legacy_behavior_is_disabled_then_a_double_dash_specifies_that_further_command_line_args_will_be_treated_as_arguments()
63-
{
64-
var option = new Option<string[]>(new[] { "-o", "--one" });
65-
var argument = new Argument<string[]>();
66-
var rootCommand = new RootCommand
67-
{
68-
option,
69-
argument
70-
};
71-
72-
var result = new CommandLineBuilder(rootCommand)
73-
.EnableLegacyDoubleDashBehavior(false)
74-
.Build()
75-
.Parse("-o \"some stuff\" -- -o --one -x -y -z -o:foo");
76-
77-
result.HasOption(option).Should().BeTrue();
78-
79-
result.GetValueForOption(option).Should().BeEquivalentTo("some stuff");
80-
81-
result.GetValueForArgument(argument).Should().BeEquivalentSequenceTo("-o", "--one", "-x", "-y", "-z", "-o:foo");
82-
83-
result.UnparsedTokens.Should().BeEmpty();
84-
}
85-
86-
[Fact]
87-
public void When_legacy_behavior_is_disabled_then_a_second_double_dash_is_parsed_as_an_argument()
147+
public void Subsequent_tokens_matching_argument_will_be_treated_as_unparsed_tokens()
88148
{
89-
var argument = new Argument<string[]>();
149+
var argument = new Argument<int[]>();
90150
var rootCommand = new RootCommand
91151
{
92152
argument
93153
};
94-
95154
var result = new CommandLineBuilder(rootCommand)
96-
.EnableLegacyDoubleDashBehavior(false)
155+
.EnableLegacyDoubleDashBehavior()
97156
.Build()
98-
.Parse("a b c -- -- d");
157+
.Parse("1 2 3 -- 4 5 6 7");
99158

100-
var strings = result.GetValueForArgument(argument);
101-
102-
strings.Should().BeEquivalentSequenceTo("a", "b", "c", "--", "d");
159+
result.GetValueForArgument(argument).Should().BeEquivalentSequenceTo(1, 2, 3);
103160
}
104161
}
105162
}

src/System.CommandLine/Binding/ArgumentConverter.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Collections;
55
using System.Collections.Generic;
66
using System.CommandLine.Parsing;
7-
using System.Diagnostics.CodeAnalysis;
87
using System.Linq;
98
using static System.CommandLine.Binding.ArgumentConversionResult;
109

@@ -226,7 +225,6 @@ internal static ArgumentConversionResult ConvertIfNeeded(
226225
};
227226
}
228227

229-
[return: MaybeNull]
230228
internal static T GetValueOrDefault<T>(this ArgumentConversionResult result)
231229
{
232230
return result switch

src/System.CommandLine/Parsing/ArgumentResult.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
using System.Collections.Generic;
55
using System.CommandLine.Binding;
6-
using System.Diagnostics.CodeAnalysis;
76
using System.Linq;
87

98
namespace System.CommandLine.Parsing
@@ -42,7 +41,6 @@ internal ArgumentConversionResult GetArgumentConversionResult() =>
4241
/// Gets the parsed value or the default value for <see cref="Argument"/>.
4342
/// </summary>
4443
/// <returns>The parsed value or the default value for <see cref="Argument"/></returns>
45-
[return: MaybeNull]
4644
public T GetValueOrDefault<T>() =>
4745
GetArgumentConversionResult()
4846
.ConvertIfNeeded(this, typeof(T))

src/System.CommandLine/Parsing/ParseOperation.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System.Collections.Generic;
5-
using System.CommandLine.Binding;
65

76
namespace System.CommandLine.Parsing
87
{
@@ -245,7 +244,15 @@ private void ParseRemainingTokens()
245244
}
246245
}
247246

248-
private void AddCurrentTokenToUnmatched() => (UnmatchedTokens ??= new()).Add(CurrentToken);
247+
private void AddCurrentTokenToUnmatched()
248+
{
249+
if (CurrentToken.Type == TokenType.DoubleDash)
250+
{
251+
return;
252+
}
253+
254+
(UnmatchedTokens ??= new()).Add(CurrentToken);
255+
}
249256

250257
private void AddCurrentTokenToUnparsed() => (UnparsedTokens ??= new()).Add(CurrentToken);
251258
}

src/System.CommandLine/Parsing/StringExtensions.cs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,6 @@ bool TryUnbundle(ReadOnlySpan<char> alias, int argumentIndex)
231231
return true;
232232
}
233233

234-
RevertTokens(tokensBefore);
235-
return false;
236-
}
237-
238-
if (found.Type != TokenType.Option)
239-
{
240-
RevertTokens(tokensBefore);
241234
return false;
242235
}
243236

@@ -257,14 +250,6 @@ bool TryUnbundle(ReadOnlySpan<char> alias, int argumentIndex)
257250
}
258251

259252
return true;
260-
261-
void RevertTokens(int lastValidIndex)
262-
{
263-
for (int i = tokenList.Count - 1; i > lastValidIndex; i--)
264-
{
265-
tokenList.RemoveAt(i);
266-
}
267-
}
268253
}
269254

270255
bool PreviousTokenIsAnOptionExpectingAnArgument(out Option? option)

0 commit comments

Comments
 (0)