Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mandatory arguments in nested subcommands #116

Closed
b0wter opened this issue Jun 26, 2018 · 5 comments · Fixed by #192
Closed

Mandatory arguments in nested subcommands #116

b0wter opened this issue Jun 26, 2018 · 5 comments · Fixed by #192
Labels

Comments

@b0wter
Copy link

b0wter commented Jun 26, 2018

I am trying to parse something like this:

./esp device status
./esp device status $myId
./esp device add $myId
./esp device remove $myId

To do so I am using this definition:

type DeviceIdArgs =
    | [<Mandatory>] [<MainCommand>] Id of string
    with
        interface IArgParserTemplate with
            member this.Usage =
                match this with
                | Id _ -> "Id of the device to remove"

[<RequireSubcommand>]
type DeviceArgs =
    | [<CliPrefix(CliPrefix.None)>] Status of ParseResults<DeviceIdArgs>
    | [<CliPrefix(CliPrefix.None)>] Remove of ParseResults<DeviceIdArgs>
    | [<CliPrefix(CliPrefix.None)>] Add of ParseResults<DeviceIdArgs>
    with
        interface IArgParserTemplate with
            member this.Usage =
                match this with
                | Status _ -> "lists all devices currently associated with your account"
                | Remove _ -> "removes the device with the given id from your account, use * to remove all"
                | Add _ -> "adds a new device with the given id, will return a registration token"

[<RequireSubcommand>]
type EspArgs =
    | Version
    | [<CliPrefix(CliPrefix.None)>] [<First>] Account of ParseResults<AccountArgs>
    | [<CliPrefix(CliPrefix.None)>] [<First>] Device of ParseResults<DeviceArgs>
    | [<CliPrefix(CliPrefix.None)>] [<First>] Firmware of ParseResults<FirmwareArgs>
    with
        interface IArgParserTemplate with
            member this.Usage =
                match this with
                | Version -> "echos the version of this tool"
                | Account _ -> "create a backend account, or login to one"
                | Device _ -> "list/remove/... devices from your account"
                | Firmware _ -> "upload and apply firmware"

This almost works like I want it to. I want to make sure that the user needs to supply an id with the commands. That why I used the MandatoryArgument for the id in the DeviceIdArgs.
Currently ./esp device add is a valid command.

@vrobinson
Copy link

vrobinson commented Jul 23, 2018

I am seeing this too:

type Direction =
    | Forward
    | Backward
    | Random

type SequenceArguments =
    | [<Mandatory>] Direction of Direction
    | Other of string
with
    interface IArgParserTemplate with
        member this.Usage =
            match this with
            | Direction _ -> "Specify the direction to use"
            | Other _ -> "Added only to test behavior when more than one arg supplied"

type MainArguments =
    | [<CliPrefix(CliPrefix.None)>] Sequence of ParseResults<SequenceArguments>
    | Version
with
    interface IArgParserTemplate with
        member this.Usage =
            match this with
            | Version _ -> "Prints the version of this program."
            | Sequence _ -> "Runs sequence subcommand."

[<EntryPoint>]
let main args =
    let argumentParser = ArgumentParser.Create<MainArguments>()

    try
        let arguments = argumentParser.Parse(inputs = args, raiseOnUsage = true)
        printfn "%A" arguments

    with e ->
        printfn "%s" e.Message

I expect these to throw and write out the help:

> my.exe sequence
[Sequence []]

> my.exe sequence --other test
[Sequence [Other "test"]]

Note that no arguments , --help, --version, sequence --help, and sequence --direction all work as expected:

> my.exe
[]

> my.exe --help
USAGE: ......

> my.exe --version
[Version]

> my.exe sequence --help
USAGE: ......

> my.exe sequence --direction
ERROR: argument '--direction' must be followed by <forward|backward|random>.
USAGE: ....

> my.exe sequence --direction forward
[Sequence [Direction Forward]]

Am I missing something in how I should be using the library? Or is this a bug?

@jcmrva
Copy link

jcmrva commented Aug 1, 2023

I tried adding [<Mandatory>] to a few subcommands today and noticed it wasn't working, so I'd say this is still a bug. Using PostProcessResult makes an argument mandatory, so it's not too hard to work around.

@bartelink
Copy link
Member

@jcmrva the chances are #192 will ship the fix (AFAICT it is the first nuget release that includes #127)

@bartelink
Copy link
Member

@jcmrva FYI 6.1.2 is on nuget

@jcmrva
Copy link

jcmrva commented Dec 13, 2023

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants