Go language is getting increasingly popular when it comes to writing microservices and commmand-line tools. It easily lets you compile a complicated application into a single binary, it can cross-compile from any OS to any other OS the Go compiler supports.
Go compiler has this nice LDFLAGS
trick to assign values to the variables in the
program at the compile time. So if you have a Version
variable in your program
you can compile it as:
$ go build -ldflags "-X main.Version=2.0.0"
This trick is really popular that pretty much everybody distributing Go binaries are using it to embed app version, git commit number etc. to the binaries. Learn more about it here and here.
Problem is, you will easily end up with the following command:
$ go build -ldflags "-X main.BuildDate=`date -u --rfc-3339=seconds | sed -e 's/ /T/'` \
-X main.GitCommit=`git rev-parse --short HEAD` \
-X main.GitBranch=`git symbolic-ref -q --short HEAD` \
-X main.State=`if [ -n "$(git status --porcelain)" ]; then echo 'dirty'; fi` \
-X main.Version=`<./VERSION`"
and find yourself creating a Makefile
for it. Ugh…
Enter govvv
I wrote this go build
wrapper that handles all this jazz for you. It’s called
govvv. Check it out on GitHub.
You just call govvv build
instead of go build
without an -ldflags
argument
and it handles it all for you:
govvv is a very-opinionated take on Go binary versioning problem. It offers you various variables, some of them are:
main.BuildDate
main.GitCommit
+main.GitState
(e.g. 85f5a13-dirty)main.GitBranch
main.Version
if there is a./VERSION
file in your repo
Read the documentation to learn more.
Why govvv
?
Well, mostly because repeating the same go build -ldflags ...
over and over
again sucks. govvv
gives you a predefined set of variables that will be
provided to your program at compile-time.
govvv
honors your existing -ldflags
and works well with them.
Also, govvv
itself is compiled with govvv
. What’s more to say?
Why not govvv
?
govvv
will be yet another external depdency to your project. It is not a
package you import, but it is a tool like go lint
that you go get
in your
build jobs.
I know, it sucks, and you should decide whether it is better than copypasting the same Makefile around. You can download a binary release or just vendor the code into your build environment to build it offline.
Let me know in the comments what you think, how govvv
can be better
and don’t forget to check out govvv on GitHub:
Leave your thoughts