jawher / mow.cli

A versatile library for building CLI applications in Go
MIT License
872 stars 55 forks source link

Handle sharing of options and arguments between subcommands #87

Open nim-nim opened 5 years ago

nim-nim commented 5 years ago

I'd like to use mow cli to implement sub commands that share a core of common options and arguments

My understanding is that it is not possible right now in mow cli without redeclaring options and args in every sub (otherwise why would the reddit example duplicate the account declaration).

Please add a way to reuse option/arg between subs to avoid the usual drift when cut and parting

If I'm wrong and it is possible today, please clarify the documentation on that point.

Lastly thanks a lot for a nicely documented project. Good documentation is the main reason I chose mow cli over alternatives.

3coma3 commented 3 years ago

I would need to confirm and test, but maybe this can be done by assigning the same handler to many subcommands? Pass some value to the handler so it knows what subcommand it should be handling at any point. Hope I didn't misunderstood.

3coma3 commented 3 years ago

I have an initial positive result. I'm writing a CLI interface to a rest service, and this code appears to do the trick:

func main() {
    restClient := cli.App("restclient", "rest client")

....(toplevel configuration)

    restClient.Command("GET", "issue GET", func(cmd *cli.Cmd) { cmdMethod("get", cmd) })
    restClient.Command("POST", "issue POST", func(cmd *cli.Cmd) { cmdMethod("post", cmd) })
    restClient.Command("PUT", "issue PUT", func(cmd *cli.Cmd) { cmdMethod("put", cmd) })
    restClient.Command("DELETE", "issue DELETE", func(cmd *cli.Cmd) { cmdMethod("delete", cmd) })

    restClient.Run(os.Args)
}

func cmdMethod(method string, cmd *cli.Cmd) {
    cmd.Spec = "ENDPOINT ARGS..."

    var (
        endpoint = cmd.StringArg("ENDPOINT", "", "endpoint for the request")
        args     = cmd.StringsArg("ARGS", []string{}, "arguments for the request")
    )

    cmd.Action = func() {
        fmt.Printf("Method: %s\nEndpoint %s\nArgs: %v\n", method, *endpoint, *args)
        cli.Exit(0)
    }
}