Go is great, but I just had to do something about its borderline insane dependency management.
Being able to do
import github.com/foo/bar is cute, but there’s very little guarantee that dependencies won’t change overnight, and no practical way of pinning stuff to a specific version/revision. Having a strong desire to avoid a repeat of my early experiences with NodeJS, where stuff like
express broke all of my code a few weeks down the road, I started looking for solutions early on.
But all the approaches I came across required third-party tools that are entirely too much hassle to set up and use reproducibly, so after a little experimentation, I converged on a rather lazy approach that mimics my usual Python pattern:
GOPATH to a
vendor directory inside each project repository,
go dep into that and clean out the
.hg folders in order to commit all the dependencies together with the project.
It’s a little wasteful in terms of storage, but perfectly doable for my ongoing projects and ensures that I’ll be able to rebuild things six months down the line. Plus it’s trivial to automate with a
Makefile like so (which also makes it easy for me to do cross-compiles):
export GOPATH:=$(shell pwd)/vendor export PATH:=$(PATH):$(GOPATH)/bin BINARY=foobar $(BINARY): *.go go build -o $(BINARY) deps: mkdir -p vendor go get github.com/rakyll/globalconf go get github.com/efarrer/iothrottler find vendor -name .git | xargs rm -rf find vendor -name .hg | xargs rm -rf git add vendor/src clean: rm -f $(BINARY) go fmt *.go pi: GOARCH=arm GOARM=6 go build -o $(BINARY)-rpi synology: GOARCH=arm GOARM=5 go build -o $(BINARY)-syno
So to add a dependency I just add another
go get line, do a
make deps and all the required code is added to the project. To update a dependency, I just remove its files and do it again. A trifle unsubtle, for sure, but it works, and has the additional side benefit of my being able to organize my projects anywhere on the filesystem without having to submit to Go’s “there can be only one way to organize your code” silliness.
make is available pretty much everywhere and not something that is likely to go out of fashion (outside the NodeJS world, that is, where they keep reinventing it), I think this solves my problems for the foreseeable future — or until Go standardizes on something at least as simple to use and maintain.