Command-Line Parsing Libraries for Go

I'm working on a project written in Go, and I've gotten to the point where I need to pick a command-line parsing library. I'm not fond of the standard flag package for a couple of reasons:

So I thought I'd shop around and see what's out there. What follows are my impressions of all the command-line parsing libraries listed in the Go Project Dashboard.

Disclaimer: I'm the original author of the Python standard library module optparse, so I'm biased in favour of convenient, automated conversion of command-line options to programmer-accessible variables. I also like automatic generation of nice-looking help. And I prefer GNU style:

Executive summary: I evaluated 8 of the libraries listed in the Go Project Dashboard. Three of them look promising:

The remainder appear to be incomplete and/or abandoned (eg. they don't build, are undocumented, or have no unit tests).

All evaluations were done with Go 1.0.3 using the latest version of each package as of December 18, 2012.

launchpad.net/gnuflag

Claims to be a compatible with the standard flag package, but supports GNU/POSIX syntax instead.

Pros:

  • mostly works as advertised: implements some of GNU/POSIX syntax
  • documented
  • tested
  • compiles and works

Cons:

  • does not conform to current "go build" rules (but the fix is trivial)
  • no support for aliases: -q and --quiet are entirely different options, and will get separate entries in help output
  • does not support option clustering (-ab equivalent to -a -b)
  • similarly, does not treat -abfoo as equivalent to -a -b foo
  • does not allow abbreviation of long options
  • default help output is ugly (but gnuflag provides an easy hook to override its help output)

code.google.com/p/goargcfg

Undocumented, so I did not evaluate it.

github.com/droundy/goopt

Like gnuflag, claims to be compatible with flag but support GNU/POSIX syntax. I could not verify this for myself, since it does not build.

Pros:

  • documented
  • comes with an example program

Cons:

  • does not build with "go build" or with the supplied Makefile (appears to predate "go build")
  • no unit tests (there is a test program, but it doesn't build either)

github.com/gaal/go-options

Yet another implementation of GNU/POSIX syntax, but using a totally different API from flag. You write a big string that describes all of your options, and the library parses it at runtime and then parses the command line. Panics if your specification is malformed.

Pros:

  • mostly works as advertised: implements some of GNU/POSIX syntax
  • nicely documented
  • tested
  • easy-to-use API
  • generates decent-looking help
  • compiles and works (modulo limitations below)

Cons:

  • does not support option clustering (-ab equivalent to -a -b)
  • similarly, does not treat -abfoo as equivalent to -a -b foo
  • sloppy syntax: treats -verbose equivalent to --verbose
  • some people might dislike the dynamic API and prefer compile-time checking (doesn't bother me)

github.com/fd/options

Similar idea to go-options, but the documentation is very thin. As a result, I was unable to get it to work.

Cons:

  • insufficient documentation
  • does not work (at least not for me)
  • generated help is not very helpful

code.google.com/p/optparse-go

Appears to be based on my Python module optparse, so I have an inherent bias in favour of this one. Unfortunately, it doesn't build.

Pros:

  • should implement all of GNU/POSIX syntax, since optparse does
  • should support option aliases, since optparse does
  • should support abbreviation of long options, since optparse does

(the above are presumptions, not verified by reading the code or trying it)

Cons:

  • not compatible with "go build" (mixed packages in same directory)
  • uses lots of obsolete library packages (needs "go fix")
  • even then, it still doesn't compile
  • no documentation

code.google.com/p/opts-go

Pros:

  • some documentation

Cons:

  • documentation doesn't give high-level overview; you just have to figure it out
  • no unit tests (there are two *_test.go files, but they test almost nothing)
  • does not treat --file foo equivalent to --file=foo
  • doesn't support abbreviation of long options
  • help generation code is incomplete -- doesn't actually generate help

github.com/ogier/pflag

Yet another implementation of GNU/POSIX syntax using the same API as flag.

Pros:

  • documented
  • unit tests
  • supports long and short options
  • supports option clustering
  • treats -abfoo equivalent to -a -bfoo

Cons:

  • not compatible with "go build" / "go test" (but the fix is trivial)
  • no support for abbreviating long options
  • does not treat --file foo equivalent to --file=foo
Author: Greg Ward
Published on: Dec 23, 2012, 1:20:13 AM
Permalink - Source code