Required environment variable
Closed this issue · 5 comments
The spec doesn't seem to provide for an option to be required either by supplying an environment variable and/or supplying a command line option.
eg.
package main
import (
"fmt"
"os"
"github.com/jawher/mow.cli"
)
func main() {
app := cli.App("test", "test")
app.Command("cmd", "command", func(cmd *cli.Cmd) {
param := cmd.String(cli.StringOpt{
Name: "param",
EnvVar: "PARAM",
})
cmd.Spec = "--param"
cmd.Action = func() {
fmt.Println("param", *param)
}
})
app.Run(os.Args)
}
i'd like this program to succeed if the program is run as either myapp --param foobar
or PARAM=foobar myapp
but print the usage info otherwise if both are omitted.
I guess I can make the argument optional in the Spec and then check it from within the action, but it seems like a common enough use case that mow.cli would have a better way of specifying it.
@gwatts Thanks for raising the issue.
This is indeed a good suggestion.
I myself ran into this many times.
@jawher do you have any thoughts on how you would implement this? I can probably create a PR
@gwatts Actually I worked a bit on this, and it turns out that it's a tiny modification to the code, which surprised me. I'll have to look at it a bit more to be sure that it doesn't break anything else. Stay tuned !
But if you want to take a stab at it, the general idea is:
- when an option is created, it is pre-initialized with either the value from the env var if it exists, or the user specified value.
- the user spec is transformed into a finite state machine (FSM), where a required option is represented with a transition from a state A to B
- while traversing the generated FSM, as of now, if a required option is not found in the user input, the traversal of this part is considered as failed
What needs to be done is: if no transition for an option is found, do not bail out immediately. Instead, check if a value for this option is already set. If that's the case, consider the traversal as successful.
@jawher that seems simple enough, though i was really wondering if you thought there was a need to be able to specify that behaviour - ie. that falling back to an env var was ok for a required parameter, or whether it should just always work that way.
Seems reasonable to me that that should be standard behaviour, but then that happens to fit my use case ;-)