Skip to content

Commit 8883f06

Browse files
authored
Don't consume the terminator during parsing. (#168)
Fixes #130.
1 parent ca89041 commit 8883f06

File tree

5 files changed

+43
-7
lines changed

5 files changed

+43
-7
lines changed

Sources/ArgumentParser/Parsing/ArgumentSet.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,8 @@ extension ArgumentSet {
348348
try parseValue(argument, parsed, origin, update, &result, &usedOrigins)
349349
}
350350
case .terminator:
351-
// Mark the terminator as used:
352-
result.set(ParsedValues.Element(key: .terminator, value: 0, inputOrigin: [origin]))
351+
// Ignore the terminator, it might get picked up as a positional value later.
352+
break
353353
}
354354
}
355355

Sources/ArgumentParser/Parsing/CommandParser.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ extension CommandParser {
8585
try checkForBuiltInFlags(split)
8686

8787
// We should have used up all arguments at this point:
88-
guard split.isEmpty else {
88+
guard !split.containsNonTerminatorArguments else {
8989
// Check if one of the arguments is an unknown option
9090
for (index, element) in split.elements {
9191
if case .option(let argument) = element {

Sources/ArgumentParser/Parsing/SplitArguments.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,20 @@ extension SplitArguments.Element {
196196
}
197197

198198
extension SplitArguments {
199+
/// `true` if the arguments are empty.
199200
var isEmpty: Bool {
200201
elements.isEmpty
201202
}
202-
203+
204+
/// `true` if the arguments are empty, or if the only remaining argument is the `--` terminator.
205+
var containsNonTerminatorArguments: Bool {
206+
if elements.isEmpty { return false }
207+
if elements.count > 1 { return true }
208+
209+
if case .terminator = elements[0].element { return false }
210+
else { return true }
211+
}
212+
203213
subscript(position: Index) -> Element? {
204214
return elements.first {
205215
$0.0 == position

Tests/ArgumentParserEndToEndTests/OptionGroupEndToEndTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import ArgumentParser
1616
final class OptionGroupEndToEndTests: XCTestCase {
1717
}
1818

19-
struct Inner: TestableParsableArguments {
19+
fileprivate struct Inner: TestableParsableArguments {
2020
@Flag(name: [.short, .long])
2121
var extraVerbiage: Bool
2222
@Option(default: 0)
@@ -33,7 +33,7 @@ struct Inner: TestableParsableArguments {
3333
}
3434
}
3535

36-
struct Outer: TestableParsableArguments {
36+
fileprivate struct Outer: TestableParsableArguments {
3737
@Flag()
3838
var verbose: Bool
3939
@Argument()
@@ -53,7 +53,7 @@ struct Outer: TestableParsableArguments {
5353
}
5454
}
5555

56-
struct Command: TestableParsableCommand {
56+
fileprivate struct Command: TestableParsableCommand {
5757
static let configuration = CommandConfiguration(commandName: "testCommand")
5858

5959
@OptionGroup()

Tests/ArgumentParserEndToEndTests/RepeatingEndToEndTests.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,32 @@ extension RepeatingEndToEndTests {
129129

130130
// MARK: -
131131

132+
fileprivate struct Outer: ParsableCommand {
133+
static let configuration = CommandConfiguration(subcommands: [Inner.self])
134+
}
135+
136+
fileprivate struct Inner: ParsableCommand {
137+
@Flag()
138+
var verbose: Bool
139+
140+
@Argument(parsing: .unconditionalRemaining)
141+
var files: [String]
142+
}
143+
144+
extension RepeatingEndToEndTests {
145+
func testParsing_subcommandRemaining() {
146+
AssertParseCommand(
147+
Outer.self, Inner.self,
148+
["inner", "--verbose", "one", "two", "--", "three", "--other"])
149+
{ inner in
150+
XCTAssertTrue(inner.verbose)
151+
XCTAssertEqual(inner.files, ["one", "two", "--", "three", "--other"])
152+
}
153+
}
154+
}
155+
156+
// MARK: -
157+
132158
fileprivate struct Qux: ParsableArguments {
133159
@Option(parsing: .upToNextOption) var names: [String]
134160
@Flag() var verbose: Bool

0 commit comments

Comments
 (0)