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 email@example.com
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.0version to make sure it works against the Kubernetes version I’m using.
After that step, the directory layout looks like in the following:
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
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:
- In your repo you should at least include
- You can include the
vendor/subdirectory, and …
- … if you include the
- your repo gets bigger :(
- pull request diffs can get more complicated to deal with :(
- guarantees reproducible builds as it decouples you from upstream changes :)
- it doesn’t require the user of your repo to execute an additional
dep ensurein 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
Hacker Noon is how hackers start their afternoons. We’re a part of the @AMI family. We are now accepting submissions and happy to discuss advertising & sponsorship opportunities.
If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories. Until next time, don’t take the realities of the world for granted!