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.