With the release of Go 1.5 comes experimental support for vendor packages. We found this setup to be so useful we pivoted Glide, the Go package manager, to focus on supporting this new vendor setup. In this post I'll walk through how it works.
Turning On The Vendor Support
The vendor support in Go 1.5 is opt-in. To enable it you need to set the environment variable
1. For example,
Once this is set the
go tool will will look for vendor packages in the
vendor directory for a project. The directory structure within the
vendor directory mirrors that of
$GOPATH/src and comes first when the
go tool searches for packages.
The structure looks like:
- myProject (Your project) | |-- main.go (Your main go code can live here) | |-- mySubpackage (You can create your own subpackages, too) | | | |-- foo.go | |-- vendor |-- github.com | |-- Masterminds | |-- ... etc.
Beyond this basic support for a
vendor directory the
go tool provides little help. That means it doesn't provide the tooling to manage packages in this directory. That's where Glide comes in.
The Basics of Glide
Once you have the
glide tool installed your project needs two things.
First, there is the
glide.yaml file where packages and their versions are documented. You can either create this by hand or use the
glide init function to create one for you. The format looks like:
package: github.com/Masterminds/glide import: - package: github.com/kylelemons/go-gypsy subpackages: - yaml - package: github.com/Masterminds/cookoo ref: master repo: email@example.com:Masterminds/cookoo.git vcs: git subpackages: - . - package: github.com/Masterminds/vcs - package: github.com/codegangsta/cli
package top level property is the name of your project. Under
import is a list of the packages to pull into the
vendor directory and manage.
If the package name, using the
package key, is the only element the latest commit on the default branch will be be used. This is the same version
go get retrieves if it were to do any management of the
ref keys for an import are where things get interesting. This allows you to set version control system, repo, and reference. For example, a package name could be
github.com/Masterminds/cookoo. But, the repo could be
firstname.lastname@example.org/mattfarina/cookoo where I keep a fork. The right import path will be used along with my repo of choice. No import rewriting required.
ref key allows you to set any reference supported by the underlying VCS. That includes branches, tags, and individual commit ids.
Once you have a
glide.yaml file defining your packages you can use the
glide up command (aliased to
install). This will fetch the packages, put them in the
vendor directory, and set the referenced version.
glide up, by default, supports recursively fetching dependencies. So, if one of your dependencies has a list of dependencies it will fetch those as well.
While we often don't vendor packages by checking them into our VCS we know others do. To support those who do vendor packages from vendors, when recursively installing updates Glide skips packages that have an existing
vendor directory. If the
vendor directory exists we assume that package is vendoring packages.
Godep, GPM, and Imports
If you add the
--import flag to
glide up or
glide get (we'll talk more about that in a minute) it will automatically import Godep and GPM dependencies into each projects
vendor directory and create a
glide.yaml file for the project populated with the packages and their versions. This works recursively with
glide up (if you don't opt out of the recursion).
If you want to convert a project, Glide has the
glide import command that can import from these systems to a
Adding Packages with glide get
go get command is handy to add packages to your
GOPATH. But, it doesn't support adding packages to a
vendor directory. So, we added
glide get [package]. Using this command will add the package to your
vendor directory and
Scripting with Glide
vendor directory is special, once you opt-in, not every tool realizes this. For example, running
go test ./... will test your package and every package in your
To support scripting we've created the
glide novendor and
glide name. The
glide name command simply returns the name of the package. The more interesting command is
novendor. It will give you all the directories except the
vendor one. So, to test your package and not the packages in
vendor you could use the command:
$ go test $(glide novendor)
Dive In, Find Bugs, and Help Us Improve
This is just the quick rundown of Glide 0.5. We hope you like it and we know it would benefit from continued improvement. Please dive in, take it for a spin, find bugs and file them, and help us improve Glide.