diff --git a/src/CommandLine/Core/Sequence.cs b/src/CommandLine/Core/Sequence.cs index 04d1b4ae..3a6147b2 100644 --- a/src/CommandLine/Core/Sequence.cs +++ b/src/CommandLine/Core/Sequence.cs @@ -34,8 +34,8 @@ private static IEnumerable OfSequence(this IEnumerable tokens, Tok return info.NextValue.MapValueOrDefault( _ => info.MaxItems.MapValueOrDefault( n => tokens.Skip(nameIndex + 1).Take(n), - tokens.Skip(nameIndex + 1).TakeWhile(v => v.IsValue())), - tokens.Skip(nameIndex + 1).TakeWhile(v => v.IsValue())); + tokens.Skip(nameIndex + 1).TakeWhile(v => v.IsValue() && !v.IsValueForced())), + tokens.Skip(nameIndex + 1).TakeWhile(v => v.IsValue() && !v.IsValueForced())); } return new Token[] { }; } diff --git a/src/CommandLine/Core/Token.cs b/src/CommandLine/Core/Token.cs index 2afee98f..c8641bdd 100644 --- a/src/CommandLine/Core/Token.cs +++ b/src/CommandLine/Core/Token.cs @@ -32,6 +32,11 @@ public static Token Value(string text, bool explicitlyAssigned) return new Value(text, explicitlyAssigned); } + public static Token ValueForced(string text) + { + return new Value(text, false, true); + } + public TokenType Tag { get { return tag; } @@ -80,16 +85,23 @@ public bool Equals(Name other) class Value : Token, IEquatable { private readonly bool explicitlyAssigned; + private readonly bool forced; public Value(string text) - : this(text, false) + : this(text, false, false) { } public Value(string text, bool explicitlyAssigned) + : this(text, explicitlyAssigned, false) + { + } + + public Value(string text, bool explicitlyAssigned, bool forced) : base(TokenType.Value, text) { this.explicitlyAssigned = explicitlyAssigned; + this.forced = forced; } public bool ExplicitlyAssigned @@ -97,6 +109,11 @@ public bool ExplicitlyAssigned get { return explicitlyAssigned; } } + public bool Forced + { + get { return forced; } + } + public override bool Equals(object obj) { var other = obj as Value; @@ -120,7 +137,7 @@ public bool Equals(Value other) return false; } - return Tag.Equals(other.Tag) && Text.Equals(other.Text); + return Tag.Equals(other.Tag) && Text.Equals(other.Text) && this.Forced == other.Forced; } } @@ -135,5 +152,10 @@ public static bool IsValue(this Token token) { return token.Tag == TokenType.Value; } + + public static bool IsValueForced(this Token token) + { + return token.IsValue() && ((Value)token).Forced; + } } -} \ No newline at end of file +} diff --git a/src/CommandLine/Core/Tokenizer.cs b/src/CommandLine/Core/Tokenizer.cs index c588a98f..e35edc9d 100644 --- a/src/CommandLine/Core/Tokenizer.cs +++ b/src/CommandLine/Core/Tokenizer.cs @@ -50,7 +50,7 @@ public static Result, Error> PreprocessDashDash( if (arguments.Any(arg => arg.EqualsOrdinal("--"))) { var tokenizerResult = tokenizer(arguments.TakeWhile(arg => !arg.EqualsOrdinal("--"))); - var values = arguments.SkipWhile(arg => !arg.EqualsOrdinal("--")).Skip(1).Select(Token.Value); + var values = arguments.SkipWhile(arg => !arg.EqualsOrdinal("--")).Skip(1).Select(Token.ValueForced); return tokenizerResult.Map(tokens => tokens.Concat(values)); } return tokenizer(arguments); diff --git a/tests/CommandLine.Tests/Fakes/Options_With_Option_Sequence_And_Value_Sequence.cs b/tests/CommandLine.Tests/Fakes/Options_With_Option_Sequence_And_Value_Sequence.cs new file mode 100644 index 00000000..c0ce7cdf --- /dev/null +++ b/tests/CommandLine.Tests/Fakes/Options_With_Option_Sequence_And_Value_Sequence.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace CommandLine.Tests.Fakes +{ + public class Options_With_Option_Sequence_And_Value_Sequence + { + [Option('o', "option-seq")] + public IEnumerable OptionSequence { get; set; } + + [Value(0)] + public IEnumerable ValueSequence { get; set; } + } +} diff --git a/tests/CommandLine.Tests/Unit/ParserTests.cs b/tests/CommandLine.Tests/Unit/ParserTests.cs index 90147ba6..bc6d77a8 100644 --- a/tests/CommandLine.Tests/Unit/ParserTests.cs +++ b/tests/CommandLine.Tests/Unit/ParserTests.cs @@ -132,6 +132,26 @@ public void Parse_options_with_double_dash() // Teardown } + [Fact] + public void Parse_options_with_double_dash_and_option_sequence() + { + var expectedOptions = new Options_With_Option_Sequence_And_Value_Sequence + { + OptionSequence = new[] { "option1", "option2", "option3" }, + ValueSequence = new[] { "value1", "value2", "value3" } + }; + + var sut = new Parser(with => with.EnableDashDash = true); + + // Exercize system + var result = + sut.ParseArguments( + new[] { "--option-seq", "option1", "option2", "option3", "--", "value1", "value2", "value3" }); + + // Verify outcome + ((Parsed)result).Value.Should().BeEquivalentTo(expectedOptions); + } + [Fact] public void Parse_options_with_double_dash_in_verbs_scenario() {