fsprojects / Argu

A declarative CLI argument parser for F#
https://fsprojects.github.io/Argu
MIT License
453 stars 75 forks source link

first-class SubCommands #117

Closed et1975 closed 5 years ago

et1975 commented 6 years ago

Description

The fact that something is a subcommand seems to be inferred based on wether or not it has sub-arguments. If my subcommand has none the parser assumes it's an option and complains that no subcommand is specified.

Repro steps

type PingArgs = 
    | Times of byte
    with
        interface IArgParserTemplate with
            member s.Usage =
                match s with
                | Times _ -> "number of times to send the ping request"

type CLIArguments =
    | TimeoutSeconds of byte
    | Port of path:string
    | Bps of bps:uint32
    | [<CliPrefix(CliPrefix.None)>] GetFWV
    | [<CliPrefix(CliPrefix.None)>] GetMAC
    | [<CliPrefix(CliPrefix.None)>] Ping of ParseResults<PingArgs>
    | [<CliPrefix(CliPrefix.None)>] Discover
    with
        interface IArgParserTemplate with
            member s.Usage =
                match s with
                | TimeoutSeconds _ -> "timeout in seconds to wait for the reply"
                | Ping _ -> "broadcast a ping packet."
                | GetFWV -> "get firmware version."
                | GetMAC -> "get mac address."
                | Discover _ -> "discover other xbee modules in the network."
                | Port _ -> "serial port where XBee is connected (eg. /dev/cu.usbserial)."
                | Bps _ -> "data rate of the port."

When asked for sub-command, the definition above would result in:

./xbee --port /dev/ttyS4 --bps 115200 getmac

no valid subcommand has been specified.

SUBCOMMANDS:

ping broadcast a ping packet.

Use 'xbee --help' for additional information.

OPTIONS:

--timeoutseconds timeout in seconds to wait for the reply --port serial port where XBee is connected (eg. /dev/cu.usbserial). --bps data rate of the port. getfwv get firmware version. getmac get mac address. discover discover other xbee modules in the network. --help display this list of options.

Expected

An attribute, or better yet model that supports expressing subcommands in their own DU. Maybe related to #68.

Actual

Either not possible or it is underdocumented (I could not see anything like this in the tests either)

Known workarounds

None that I can see.

Related information

btrepp commented 5 years ago

If this is troubling you a workaround I've been using is

type NopeArgs = 
    | [<Hidden>] NeverUsed

    with
        interface IArgParserTemplate with
            member s.Usage =
                match s with
                | NeverUsed _ -> "Never displayed"

and using ParseResults in my subcommands