Managing dependencies in Go might not be the first thing you’d be paying attention to but there comes the time when you likely have to face the task. In this post I’ll share some observations with my first steps using Go dep
from a project maintainer perspective.
Go dependency management, or vendoring as we Gophers say, has a rather longish and slightly complicated history. With Go dep the community now seems to slowly (?) but surely converge on a standard. Since I need it anyway in one of the projects I contribute to I thought it makes sense to get some hands-on knowledge under my belt, in a sandboxed environment, before I apply it ‘for real’.
OK, let’s jump right into it: first, we have to install Go dep,
which assumes a more recent version of Go installed (I’m using 1.8):
$ go get -u github.com/golang/dep/cmd/dep
Next, we’ll need a program we want to vendor, so here’s a simple example using amongst other things the Kubernetes Go client to create a primitive version of a cluster shell (side note I’m using Minishift to set up and run Kubernetes):
The goal is to vendor the packages imported in line 7 to 10. So, in order to do this, I executed in the directory where the main.go
file is located these commands:
$ dep init$ dep ensure k8s.io/client-go@^2.0.0$ dep ensure github.com/chzyer/[email protected]
Note that the last two lines are not strictly required, since dep
is smart enough to figure out the versions needed itself. In my case I needed to pin the client-go
package to the 2.0.0
version to make sure it works against the Kubernetes version I’m using.
After that step, the directory layout looks like in the following:
.├── Gopkg.lock├── Gopkg.toml├── main.go└── vendor├── cloud.google.com├── github.com├── golang.org├── google.golang.org├── gopkg.in└── k8s.io
Now I’m in the position to go build
or go install
the program and execute it. On important note and a potential pitfall at this point: unless you actually import a certain package in your source code, a dep ensure
won’t actually download the version into the vendor/
sub-directory.
Coming back to the initial question: what do I need to do now as a project maintainer to make this vendored setup available in a repo for others to use? Since I wasn’t able to find best practices around this topic, I jumped on the #vendor
channel in the Go Slack community and the friendly people (special kudos to Peter Bourgon) provided guidance:
Gopkg.toml
and Gopkg.lock
.vendor/
subdirectory, and …vendor/
subdirectory:dep ensure
in order to be able to build the program :)Summing up: while Go dep
is still early days and lacks some documentation around best practices (apparently a FAQ is coming soon) I found it simple to use and feel like I’m ready to use it in anger now.
EDIT: As pointed out by Ahmet Alp Balkan, you can generate visualizations of dependency graphs for packages via godoc.org, for example, https://godoc.org/github.com/mhausenblas/cinf?import-graph&hide=1