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 avendor
directory. When avendor
directory is found, the go tool will look intovendor/example.com/foo
, if that directory exists it will be used as the package imported with the pathexample.com/foo
. If it doesn't exist the go tool will continue upwards looking for othervendor
directories, and eventually inGOPATH
.
So given a project/directory structure like the following:
GOPATH
├── 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 (
"github.com/contd/links"
)
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/links
but 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 ofvendor
.
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