apple / swift-argument-parser

Straightforward, type-safe argument parsing for Swift
Apache License 2.0
3.31k stars 311 forks source link

postTerminator: Either confusing documentation or wrong behavior #597

Closed Jean-Daniel closed 6 months ago

Jean-Daniel commented 10 months ago

The postTerminator documentation stats:

Before parsing, capture all inputs that follow the -- terminator

But in reality, that step is performed before parsing Arguments, but after parsing Options.

I have the following code:

struct MyCommand: ParsableCommand {
  @Option(parsing: .remaining) var sshArgs: [String] = []
  @Argument(parsing:.postTerminator) var remoteCommand: [String] = []

…
}

I'm trying to parse the following command line:

mytool --ssh-args -c -p 2023 -O -f "some file" -- echo "Hello World"

and get sshArgs = [ "-c", "-p", "2023", "-O", "-f", "some file"] and remoteCommand = [ "echo", "Hello World" ]

If the documentation was accurate, remoteCommand should be performed first and capture echo "Hello World".

So, this is either the expected behavior, and the documentation requires some clarification, or the documentation is right, and postTerminator parsing is broken.

ArgumentParser version: 1.23

Swift version: swift-driver version: 1.87.1 Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1)

Checklist

Steps to Reproduce

@main
struct MyCommand: ParsableCommand {
  @Option(parsing: .remaining) var sshArgs: [String] = []
  @Argument(parsing:.postTerminator) var remoteCommand: [String] = []

  public func run() {
    print(sshArgs)
    print(remoteCommand)
  }
}

Expected behavior

sshArgs contains arguments before the terminator, and remoteCommands the arguments after the terminator.

Actual behavior

sshArgs contains everything, including the terminator.

natecook1000 commented 9 months ago

Thanks for the report, @Jean-Daniel! At this point, I think this needs to be treated as a documentation error, given that the behavior you've documented here has existed for some time, and is needed to support pass-through situations, where a command needs to capture the remainder of an input, regardless of what's there.