Clean Build Versions With DocOpt

With some recent Go projects, I’ve been using docopt.go for command line argument parsing. It greatly reduces the complexity of dealing with arguments and options. On it’s own, arguments can be processed without much work:

package main import ( "github.com/docopt/docopt.go" ) var ( githash string = "" ) func main() { usage := `Awesome Usage: awesome [--help --version --config=<file>] awesome daemon [--help --version --config <file>] awesome thing [--verbose... ] <with> <more>... Options: --help Show this screen. --version Show version. --verbose Verbose ` arguments, _ := docopt.Parse(usage, nil, true, version(), false) // ... do something with arguments } func version() string { previewVersion := "1.0.0" if len(githash) > 0 { return previewVersion + "+" + githash } return previewVersion }

What I’ve also been doing is using a small Makefile to add extra information to the version:

all: go build -ldflags "-X main.githash `git rev-parse --short HEAD`"

If the go build command is used, then the version given to docopt is just 1.0.0, but if the main.githash is set as it is in the Makefile, then the version ends up being something like “1.0.0+b74276b”.

$ ./awesome --version 1.0.0+b74276b

You can take it one step further and have the version set as a var that can easily be updated with sed or awk. An example would look something like:

package main var ( AWESOME_VERSION = "1.0.0" )

Using awk to update the version would look like this: