A Makefile for Go Vendor Experiment

February 7, 2016

I recently started using the new Go vendor experiment in one of my projects and I really love not having rewritten go imports just so I can vendor my dependencies. I’ve always thought of it as a horrible hack to solve the problem and it was not very clear how to really use your code that way.

But with the new vendor directory inside your project using `./…` to specific all your packages using commands like `go test -v ./…` will select all the packages of your vendor directory along with all of yours too. https://github.com/golang/go/issues/11659

My first idea to solve this was to simply lower the number of packages I was making and specify them all manually for the commands, but Godeps noticed this problem too and offered a solution

$ go <cmd> $(go list ./… | grep -v /vendor/)

So to run your tests you could simply run this…

go test -v -race $(go list ./... | grep -v /vendor/)

Which is nice cause it’s some kind of solution, but I didn’t like having to suddenly type so much compared to before so I wanted to put it in a Makefile. It was a bit tricky for me too since I don’t usually use Makefiles for anything and I needed to use a feature that wasn’t very well discussed online.

ENV=GO15VENDOREXPERIMENT=1
PACKAGES=$(shell go list ./... | grep -v /vendor/)
test:
$(ENV) go test -v -race $(PACKAGES)

First off, since we’re using the vendor experiment in Go 1.5 we need to pass the flag since we could be running this anywhere and it’s possible the proper environment variables haven’t been set.

Next I used the shell-thingy (which was only discovered how to properly use after lots of trial and error) to store the result of that shell expression which contains all of our own packages without the ones we vendor.

We then run the command `go text -v -race` with the environment variables and correct packages and the tests run like they used to.

Now all you have to do is say `make test`. And more commands can be easily added to this Makefile for other commands you’re used to running on all your packages.