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
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
directory mirrors that of
$GOPATH/src and comes first when the
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
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
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
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 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
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
novendor. It will give you all the directories except the
one. So, to test your package and not the packages in
vendor you could use
$ 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.