In the java/scala world, I'm used to parsing arguments using high level declarative syntax which you control directly. For example:
In the above argument parser, you recursively iterate through a series of commandline options. At each iteration, you might append a new field to a hash map.
Quick introduction
In golang things are different and its more common to use the Flag library, then to write your own commandline parser using native language constructs. Possibly because golang's string/collections implementations aren't as fancy ? Not sure. Or maybe because of the fact that Golang was written for systems software which relies heavily on command line arguments.
Flag library parses arguments for you in a declarative way, and can do nice things like bind to struct variables for you, like this...
flag.StringVar(&testContext.KubeConfig, "kube_config", "", "Path to kubeconfig containing embeded authinfo.")
When you run your program, flag will have remembered all the calls you made to it - and you can call "flag.Parse", which will bind all the options given at the commandline according to the rules you provided. For example, the above would take an option like --kube_config=/tmp/cfg.
Back to the point...
But at the time of this writing it doesn't provide an direct option to directly fail if unknown args are given. In particular, I recently found that I was launching a go based program with extra args (Which I assumed were doing something important!) which were being totally silently ignored.
But, flag does "remember" how many args are remaining after it did all its bindings, and you can access that by calling flag.NArgs().
And thus you can do something like this...
+ if flag.NArg() > 0 || opts.help {}
fmt.Fprintf(os.Stderr, "Usage: %s [OPTION]...\n", os.Args[0])
And thats it !

No comments:
Post a Comment