## Overview This gist is based on the information available at [golang/dep](https://github.com/golang/dep), only slightly more terse and annotated with a few notes and links primarily for my own personal benefit. It's public in case this information is helpful to anyone else as well. I initially advocated [Glide](https://glide.sh/) for my team and then, more recently, [vndr](https://github.com/LK4D4/vndr). I've also taken the approach of exerting direct control over what goes into `vendor/` in my Dockerfiles, and also work from isolated GOPATH environments on my system per project to ensure that dependencies are explicitly found under `vendor/`. At the end of the day, vendoring (and committing `vendor/`) is about being in control of your dependencies and being able to achieve reproducible builds. While you can achieve this manually, things that are nice to have in a vendoring tool include: * automated ability to determine all of a project's dependencies * identify the latest version of a package that satisifies all dependencies in the dependency graph * ability to specify a range of acceptable versions of packages that satisfy the project's dependencies * ability to pin the range of acceptable versions to a set of explicit versions used for reproducible builds * ability to prune any unnecessary packages from the resulting vendor set Because it looks like dep is the [future](https://github.com/golang/dep/wiki/Roadmap) for Go vendoring, it makes sense to embrace dep now even though it is [still undergoing change](https://github.com/golang/dep#current-status) until it is merged into the toolchain and reaches a v1 release. As noted in the [roadmap](https://github.com/golang/dep/wiki/Roadmap), there is no "guarantee dep will be accepted"; yet, nevertheless, there appears to be a good deal of momentum behind dep at this point. ## Get (or update) dep ```sh $ go get -u github.com/golang/dep/cmd/dep ``` ## Initialize your project > Run `dep init` to initialize your project. dep will analyize your project, identify your dependencies, pick the highest compatible version for each dependency, generate a [Gopkg.toml](https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md) manifest and Gopkg.lock files (see [here](https://github.com/golang/dep/issues/119#issuecomment-275467269) for background on the two file format), and install dependencies in `vendor/`. ```sh $ dep init ``` #### Notes If you are already using glide, godep, vndr, or govend, dep will convert the [existing dependency management file](https://github.com/golang/dep/blob/master/docs/FAQ.md#what-external-tools-are-supported). See this [issue](https://github.com/golang/dep/issues/186) and this [interface](https://github.com/golang/dep/blob/074cec3e7ff795efa421f57db333c4328402f01c/cmd/dep/root_analyzer.go#L20) for implementing configuration importers. If you have an existing `vendor/` directory, it will be backed up to `_vendor-TIMESTAMP/`. You can tell dep to resolve dependencies from `GOPATH` before resorting to network mode with `dep init -gopath`. See [here](https://github.com/golang/dep/blob/master/docs/FAQ.md#how-do-i-make-dep-resolve-dependencies-from-my-gopath) for a bit more detail. ## Confif option to remove extra files from vendor directory tree You can limit the amount of code you will commit in the repository by setting `prune` options in your `Gopkg.toml` file. Prune is now handled by `dep ensure`. A safe default config for prune is : ``` [prune] unused-packages = true go-tests = true ``` ## Usage #### Installing dependencies > Run `dep ensure` to ensure `vendor/` is in the correct state for your configuration. ```sh $ dep ensure ``` dep's *solver* regenerates `Gopkg.lock` if it detects any change in your code imports and/or `Gopkg.toml`. If this is the case, then the new `Gopkg.lock` file is used to completely rewrite `vendor/` (at some point [vendor verification](https://github.com/golang/dep/issues/121) will allow the contents of `vendor/` to also be checked for consistency with `Gopkg.lock`, updating only what is necessary to make the contents current). #### Note This process may be slow for large projects, especially the first time as dependencies are cloned or when it hasn't been run in a while and there are many changesets to fetch. dep manages a cache at `$GOPATH/pkg/dep` to mitigate fetch overhead. See [here](https://github.com/golang/dep/blob/master/docs/FAQ.md#why-is-dep-slow) for further details. There are a number of variations to this command. Run `dep ensure -examples` for details. One in particular to note that may be relevant when creating a Dockerfile is `dep ensure -vendor-only`. #### Adding a dependency > Use `dep ensure -add` to update your configuration with a new dependency. ```sh $ dep ensure -add github.com/foo/bar github.com/foo/baz... ``` dep will update your `Gopkg.toml`, `Gopkg.lock`, and `vendor/` to the latest version unless version constraints are applied; for example: ```sh $ dep ensure -add github.com/foo/bar@1.0.0 github.com/foo/baz@master ``` #### Checking status of dependencies > Use this to detect a mismatch between the configuration and state of your project One way this can happen is when you import a package that is resolved when you build because it is found in your `GOPATH`, but it has not been added to your configuration (and therefore is not present in the generated `Gopkg.lock` file). ```sh $ dep status ``` Use this information to update your configuration with `dep ensure -add` as appropriate. #### Updating dependencies > dep will update your dependencies to the latest versions that satisify the constraints specified in `Gopkg.toml`. *Preferred* ```sh $ dep ensure -update github.com/foo/bar github.com/foo/baz... ``` *Possible, but being specific is preferred* ```sh $ dep ensure -update ``` #### Note The latest version means the latest version in a [semver range](https://github.com/golang/dep#semantic-versioning) or if depending on a branch, the tip of the branch. #### Removing dependencies 1. Remove the relevant `import` package statements and usage in your code 2. Remove the relevant `[[constraint]]` rules from `Gopkg.toml` 3. Run `dep ensure` ## Editing packages that are dependencies of your project Your project may rely on dependencies that you wish to edit. These dependencies should **not** be updated directly under `vendor/` since they can be overwritted by dep. Instead, volatile dependencies should be removed manually from under `vendor/` and then placed in the appropriate location in your $GOPATH. When building, Go will first search your `vendor/` directory, then it will search your $GOPATH. If the package update has been pushed to its public repo, then simply run `dep ensure -update` as described in [Changing Dependencies](#changing-dependencies). ## Gopkg.toml While `dep init` will generate a `Gopkg.toml` file and `dep ensure -add` will add new dependencies to it, there are occasions where you will need to edit this file manually besides when removing a dependency. The format is straightforward and consists of the following elements: * `required` * `ignored` * `metadata` (under the root as well as under `constraint` and `override` declarations; ignored by dep) * `constraint` * `override` * `version` (a property of `constraint` and `override` declarations) There are important (and subtle) details involved, so it is best to read the [spec](https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md) directly. ## Links [GitHub](https://github.com/golang/dep) [Gopkg.toml format](https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md) [FAQ](https://github.com/golang/dep/blob/master/docs/FAQ.md) [dep semver](https://github.com/golang/dep#semantic-versioning)