Compulsory command line flags using 'flag' package

1,423 views
Skip to first unread message

ahmet

unread,
Nov 26, 2013, 2:33:50 AM11/26/13
to golan...@googlegroups.com
Hi,

While using "flag" pkg, what is the idiomatic way of making specific command line parameters compulsory instead of providing them a default value and using it? Let's say you have to get an input integer via a flag and all ints are valid input, so you can't have a sentinel value and validate against it. In this case, using something like

if (flag.Lookup("name") == nil) {
    // tell user flag is required
}

the correct approach?

Also, what is the idiomatic way to print usage string without default values (I see we have only PrintDefaults here).

Thanks,
Ahmet.

Luther

unread,
Nov 27, 2013, 12:05:49 AM11/27/13
to golan...@googlegroups.com
On Tuesday, November 26, 2013 2:33:50 AM UTC-5, ahmet wrote:
While using "flag" pkg, what is the idiomatic way of making specific command line parameters compulsory instead of providing them a default value and using it? Let's say you have to get an input integer via a flag and all ints are valid input, so you can't have a sentinel value and validate against it. In this case, using something like

if (flag.Lookup("name") == nil) {
    // tell user flag is required
}

the correct approach?

If an argument is compulsory, make it a positional argument, not a flag. This is standard practice in GNU-ish command line programs.

i, err := strconv.Atoi(flag.Arg(0))
if err != nil {
// tell user integer is required
}

Carlos Castillo

unread,
Nov 27, 2013, 2:57:11 PM11/27/13
to golan...@googlegroups.com
Your method of determining if a flag has been set won't work. The test you make flag.Lookup("name") == nil will only return true if no flag variable with that name exists, meaning you didn't create a flag with that name. The return value of the Lookup method is a Flag structure which represent the flags that have been assigned to the default command line parser.

The only way to change the output of the usage message is to change the value of the flag.Usage function variable so that it does something other than call flag.PrintDefaults (ie: write your own usage message).

To make a mandatory flag (or at least be able to tell if a flag was set), two techniques come to mind:
 - Create a new Value type, so you can track if Set() was ever called.
 - Use a different type of flag, such as a string or float64 flag, where it's easy to tell if the input is invalid (ie: when it's not a valid integer), but it's possible to pass a value that is an integer, and set the default to an invalid value

One way to do the first: http://play.golang.org/p/PnKgUFGUSw
One way to do the second: http://play.golang.org/p/tHSlGmmYCv

The latter involves little code, but has some problem cases (using strings would be more code but more accurate). The former is a lot more code, but give a lot more control over the specifics, and is more logically connected to what you are attempting to track.
Reply all
Reply to author
Forward
0 new messages