Go tip of the week: GNU-style flags—almost
Go's flag package is often criticized for only having single-dash flags. The well-established GNU-style flags distinguish between long flag names that start with two dashes and single-letter flags starting with a single dash, such as:
grep -f <file> ...
grep --file=<file> ...
Go apps, on the other hand, would have flags like so:
go build -race .
But this is only half the truth. Go's standard flag
package actually knows double-dash flags and allows defining a flag and a shorthand version (like the --file
and -f
examples above).
First, the flag
package is
agnostic about whether you prepend one or two dashes to a flag. All of these variants would be valid:
go build -race .
go build --race .
go build -a .
go build --a .
Second, you can map two flags to the same variable, to create a flag/shorthand pair. In the following code, either of the variants --bugfix
and -b
sets the same variable, bugfix
, to true
.
var bugfix bool
flag.BoolVar(&bugfix, "bugfix", false, "Fix all bugs")
flag.BoolVar(&bugfix, "b", false, "Fix all bugs (shorthand)")
flag.Parse()
not := ""
if !bugfix {
not = "won't "
}
fmt.Printf("I %sfix your bugs.\n", not)
Since you can use one or two dashes as you wish, the usage is not exactly following the GNU rules:
> go run .
I won't fix your bugs.
> go run . -b
I fix your bugs.
> go run . -bugfix
I fix your bugs.
> go run . --bugfix
I fix your bugs.
> go run . --b
I fix your bugs.
So this is almost, but not quite, GNU-ish. Furthermore, you cannot put multiple single-character flags behind the same dash, such as -abc
instead of -a -b -c
. For this level of compatibility, you can revert to third-party packages like
github.com/spf13/pflag.