alecthomas / kingpin

CONTRIBUTIONS ONLY: A Go (golang) command line and flag parser

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ExistingDir() still checked when program run with --version

gebn opened this issue · comments

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:

  1. Do the raw CLI parsing so we know what flags & args were passed
  2. Set default values for flags
  3. Set values for all flags based on CLI (& env vars, I assume)
  4. 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.