GoVendoring

Remarks

Vendoring is a method of ensuring that all of your 3rd party packages that you use in your Go project are consistent for everyone who develops for your application.

When your Go package imports another package, the compiler normally checks $GOPATH/src/ for the path of the imported project. However if your package contains a folder named vendor, the compiler will check in that folder first. This means that you can import other parties packages inside your own code repository, without having to modify their code.

Vendoring is a standard feature in Go 1.6 and up. In Go 1.5, you need to set the environment variable of GO15VENDOREXPERIMENT=1 to enable vendoring.

Use govendor to add external packages

Govendor is a tool that is used to import 3rd party packages into your code repository in a way that is compatible with golang's vendoring.

Say for example that you are using a 3rd party package bosun.org/slog:

package main

import "bosun.org/slog"

func main() {
    slog.Infof("Hello World")
}

Your directory structure might look like:

$GOPATH/src/
├── github.com/me/helloworld/
|   ├── hello.go 
├── bosun.org/slog/
|   ├── ... (slog files)

However someone who clones github.com/me/helloworld may not have a $GOPATH/src/bosun.org/slog/ folder, causing their build to fail due to missing packages.

Running the following command at your command prompt will grab all the external packages from your Go package and package the required bits into a vendor folder:

govendor add +e

This instructs govendor to add all of the external packages into your current repository.

Your application's directory structure would now look like:

$GOPATH/src/
├── github.com/me/helloworld/
|   ├── vendor/
|   |   ├── bosun.org/slog/
|   |   |   ├── ... (slog files)
|   ├── hello.go 

and those who clone your repository will also grab the required 3rd party packages.

Using trash to manage ./vendor

trash is a minimalistic vendoring tool that you configure with vendor.conf file. This example is for trash itself:

# package
github.com/rancher/trash

github.com/Sirupsen/logrus                      v0.10.0
github.com/urfave/cli                           v1.18.0
github.com/cloudfoundry-incubator/candiedyaml   99c3df8  https://github.com/imikushin/candiedyaml.git
github.com/stretchr/testify                     v1.1.3
github.com/davecgh/go-spew                      5215b55
github.com/pmezard/go-difflib                   792786c
golang.org/x/sys                                a408501

The first non-comment line is the package we're managing ./vendor for (note: this can be literally any package in your project, not just the root one).

Commented lines begin with #.

Each non-empty and non-comment line lists one dependency. Only the "root" package of the dependency needs to be listed.

After the package name goes the version (commit, tag or branch) and optionally the package repository URL (by default, it's inferred from the package name).

To populate your ./vendor dir, you need to have vendor.conf file in the current dir and just run:

$ trash

Trash will clone the vendored libraries into ~/.trash-cache (by default), checkout requested versions, copy the files into ./vendor dir and prune non-imported packages and test files. This last step keeps your ./vendor lean and mean and helps save space in your project repo.

Note: as of v0.2.5 trash is available for Linux and macOS, and only supports git to retrieve packages, as git's the most popular one, but we're working on adding all the others that go get supports.

Use golang/dep

golang/dep is a prototype dependency management tool. Soon to be an official versioning tool. Current status Alpha.

Usage

Get the tool via

$ go get -u github.com/golang/dep/...

Typical usage on a new repo might be

$ dep init
$ dep ensure -update

To update a dependency to a new version, you might run

$ dep ensure github.com/pkg/[email protected]^0.8.0

Note that the manifest and lock file formats have now been finalized. These will remain compatible even as the tool changes.

vendor.json using Govendor tool

# It creates vendor folder and vendor.json inside it
govendor init

# Add dependencies in vendor.json
govendor fetch <dependency>

# Usage on new repository
# fetch depenencies in vendor.json
govendor sync

Example vendor.json

{

"comment": "",
"ignore": "test",
"package": [
    {
        "checksumSHA1": "kBeNcaKk56FguvPSUCEaH6AxpRc=",
        "path": "github.com/golang/protobuf/proto",
        "revision": "2bba0603135d7d7f5cb73b2125beeda19c09f4ef",
        "revisionTime": "2017-03-31T03:19:02Z"
    },
    {
        "checksumSHA1": "1DRAxdlWzS4U0xKN/yQ/fdNN7f0=",
        "path": "github.com/syndtr/goleveldb/leveldb/errors",
        "revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
        "revisionTime": "2017-04-09T01:48:31Z"
    }
],
"rootPath": "github.com/sample"

}