kingpin
kingpin copied to clipboard
ExistingDir() still checked when program run with --version
When using kingpin.Version("...")
, passing --version
means .Required()
arguments do not have to be provided. I have an argument with a .Default()
that must be an .ExistingDir()
. The default path does not exist on the system. When passing only --version
, I get an error that the default directory doesn't exist, rather than the version. Passing --version --help
means the version is printed correctly.
It would be very useful if kingpin did not check that .ExistingDir()
s actually existed if the program is run with only the --version
flag.
Hit the same issue, reproduce:
package main
import (
"github.com/alecthomas/kingpin"
)
var (
foo = kingpin.Flag("foo", "Foo").Default("foo.txt").File()
)
func main() {
kingpin.Version("0.1")
kingpin.Parse()
}
[~/goprojects/ygersie/test]$ go run kingpin.go --version
kingpin: error: open foo.txt: no such file or directory, try --help
exit status 1
I took a look at this and it's not easily fixable, AFAICT.
The issue is that internally --version
is just yet another flag like all the others. When you call .Parse()
the sequence always goes as follows:
- Do the raw CLI parsing so we know what flags & args were passed
- Set default values for flags
- Set values for all flags based on CLI (& env vars, I assume)
- Applies pre-actions, which is where
--version
is handled
The problem is that the pre-actions are able to see the flags from steps 2 & 3.
To fix this there would need to be some sort of pre-pre-action special case, maybe an "immediate action", where the presence of a particular flag can short circuit the normal processing.
This is doable, but I'm not sure what the best way to implement this in a non-hacky, extensible way would be.