Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Sources/ArgumentParser/Parsing/ArgumentSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,8 @@ extension ArgumentSet {
try parseValue(argument, parsed, origin, update, &result, &usedOrigins)
}
case .terminator:
// Mark the terminator as used:
result.set(ParsedValues.Element(key: .terminator, value: 0, inputOrigin: [origin]))
// Ignore the terminator, it might get picked up as a positional value later.
break
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/ArgumentParser/Parsing/CommandParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ extension CommandParser {
try checkForBuiltInFlags(split)

// We should have used up all arguments at this point:
guard split.isEmpty else {
guard !split.containsNonTerminatorArguments else {
// Check if one of the arguments is an unknown option
for (index, element) in split.elements {
if case .option(let argument) = element {
Expand Down
12 changes: 11 additions & 1 deletion Sources/ArgumentParser/Parsing/SplitArguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,20 @@ extension SplitArguments.Element {
}

extension SplitArguments {
/// `true` if the arguments are empty.
var isEmpty: Bool {
elements.isEmpty
}


/// `true` if the arguments are empty, or if the only remaining argument is the `--` terminator.
var containsNonTerminatorArguments: Bool {
if elements.isEmpty { return false }
if elements.count > 1 { return true }

if case .terminator = elements[0].element { return false }
else { return true }
}

subscript(position: Index) -> Element? {
return elements.first {
$0.0 == position
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import ArgumentParser
final class OptionGroupEndToEndTests: XCTestCase {
}

struct Inner: TestableParsableArguments {
fileprivate struct Inner: TestableParsableArguments {
@Flag(name: [.short, .long])
var extraVerbiage: Bool
@Option(default: 0)
Expand All @@ -33,7 +33,7 @@ struct Inner: TestableParsableArguments {
}
}

struct Outer: TestableParsableArguments {
fileprivate struct Outer: TestableParsableArguments {
@Flag()
var verbose: Bool
@Argument()
Expand All @@ -53,7 +53,7 @@ struct Outer: TestableParsableArguments {
}
}

struct Command: TestableParsableCommand {
fileprivate struct Command: TestableParsableCommand {
static let configuration = CommandConfiguration(commandName: "testCommand")

@OptionGroup()
Expand Down
26 changes: 26 additions & 0 deletions Tests/ArgumentParserEndToEndTests/RepeatingEndToEndTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,32 @@ extension RepeatingEndToEndTests {

// MARK: -

fileprivate struct Outer: ParsableCommand {
static let configuration = CommandConfiguration(subcommands: [Inner.self])
}

fileprivate struct Inner: ParsableCommand {
@Flag()
var verbose: Bool

@Argument(parsing: .unconditionalRemaining)
var files: [String]
}

extension RepeatingEndToEndTests {
func testParsing_subcommandRemaining() {
AssertParseCommand(
Outer.self, Inner.self,
["inner", "--verbose", "one", "two", "--", "three", "--other"])
{ inner in
XCTAssertTrue(inner.verbose)
XCTAssertEqual(inner.files, ["one", "two", "--", "three", "--other"])
}
}
}

// MARK: -

fileprivate struct Qux: ParsableArguments {
@Option(parsing: .upToNextOption) var names: [String]
@Flag() var verbose: Bool
Expand Down