swift-argument-parser icon indicating copy to clipboard operation
swift-argument-parser copied to clipboard

Incorrect handling of arguments with the same property name

Open rauhul opened this issue 3 years ago • 1 comments

Swift argument parser doesn't handle properties with the same name under different option groups gracefully.

The following snippet throws an error when run with no arguments, but I would expect no required arguments:

import ArgumentParser

struct Foo: ParsableCommand {
    @Option(name: .long)
    var `bar`: String = ""

    @OptionGroup
    var group: Group
    
    func run() throws { }
}

struct Group: ParsableArguments {
    @Option(name: .customLong("baz"))
    var `bar`: String?
}

Foo.main()

Output:

Error: Missing one of: '--bar <bar>', '--baz <baz>'

USAGE: foo [--bar <bar>] [--baz <baz>]

OPTIONS:
  --bar <bar>
  --baz <baz>
  -h, --help              Show help information.

ArgumentParser version: 0.4.3 Swift version:

swift-driver version: 1.20.1 Apple Swift version 5.5 (swiftlang-1300.0.13.7 clang-1300.0.15.1)
Target: arm64-apple-macosx11.0

Checklist

  • [x] If possible, I've reproduced the issue using the main branch of this package
  • [x] I've searched for existing GitHub issues

rauhul avatar Jun 03 '21 00:06 rauhul

Just ran into this issue between a few OptionGroups I have defining common values between commands. The hack I used to get around the issue for now was to namespace the actual parsed value like this:

public struct ExampleOption: ParsableArguments {
    @Option(name: [.customLong("foo")])
    var _valueExampleOption: Int // Add a prefix _ and a suffix of the type name
    public var value: Int { _valueExampleOption }

    public init() {}
}

This let me preserve the usage of value while making it so things could properly parse and function.

bscothern avatar Nov 24 '21 06:11 bscothern

Yeah, I've had the same issue as @bscothern with regards to having two ParsableArguments instances with the same internal field (eg. var enabled: Bool, in my case) and different .customLong(...) values, and they both overwrite each other. In my case, it's a @Flag.

If anyone has any pointers on where to start and/or the appropriate section to add a test case, I'm happy to investigate.

randomeizer avatar Sep 19 '22 05:09 randomeizer

I've tracked down the source of the bug, and have a PR at #495. If you want to test out my solution, my fix is in the following branch on my fork of the project:

https://github.com/randomeizer/swift-argument-parser/tree/randomeizer/322-duplicate-fields-in-OptionGroup

randomeizer avatar Sep 19 '22 20:09 randomeizer