Home About Photos Contact Archive

Today I Learned Go Part 2


This is the second part of my notes from going through a go-tooling-workshop.

The vendor Directory #

Whenever an import path example.com/foo is found in Go code, the go tool will navigate the directory tree towards the root, looking for a directory containing a vendor directory. When a vendor directory is found, the go tool will look into vendor/example.com/foo, if that directory exists it will be used as the package imported with the path example.com/foo. If it doesn't exist the go tool will continue upwards looking for other vendor directories, and eventually in GOPATH.

So given a project/directory structure like the following:

├── client
│ └── main.go
├── server
│ ├── Dockerfile
│ ├── main.go
│ ├── main_test.go
│ ├── model.go
│ ├── saved.sqlite
│ └── saved_test.sqlite
└── vendor
└── github.com
└── contd
└── links
└── links.go

The main.go file in the server directory has an import statement like so:

import (

The go tool will use the code from the vendor directory when compiling the project above even if there exists a project in the GOPATH that matches the import statement. For another project that has the same import statement in one of its go files but does not have a vendor directory, the go tool will use the code from the GOPATH root.

The internal Directory #

To further divide the visibility of Identifiers, you can use an internal directory to make identifiers only visible to a subset of packages in a project. For example, given the project structure below:

├── client
│ └── main.go
└── server
├── Dockerfile
├── internal
│ └── links
│ └── links.go
├── main.go
├── main_test.go
├── model.go

The server directory's go files have access or the ability to import github.com/contd/links/internal/linksbut the client directory cannot import from .../import/links.

The dep Tool #

There are many dependency management tools developed for go but one of the latest utilizes the vendor directory along with a few other nice features. To begin, it needs to be installed like so:

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

To setup a project to utilize dep, you run the following inside your project directory:

dep init
dep ensure -update

This will create:

  • Gopkg.toml: a file where you add restrictions and extra info about your package.
  • vendor: containing all the dependencies for your package.
  • Gopkg.lock: an autogenerated file keeping track of the contents of vendor.

Then to update a dependency to the a new version (like github.com/pkg/errors or github.com/Sirupsend/logrun) you run:

dep ensure github.com/pkg/errors@^0.8.0
dep ensure github.com/Sirupsen/logrus@1.0.0

← Home