Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
---
title: Gopkg.toml
---
The `Gopkg.toml` file is initially generated by `dep init`, and is primarily hand-edited. It contains several types of rule declarations that govern dep's behavior:
* _Dependency rules:_ [`constraints`](#constraint) and [`overrides`](#override) allow the user to specify which versions of dependencies are acceptable, and where they should be retrieved from.
* _Package graph rules:_ [`required`](#required) and [`ignored`](#ignored) allow the user to manipulate the import graph by including or excluding import paths, respectively.
* [`metadata`](#metadata) are a user-defined maps of key-value pairs that dep will ignore. They provide a data sidecar for tools building on top of dep.
* [`prune`](#prune) settings determine what files and directories can be deemed unnecessary, and thus automatically removed from `vendor/`.
Note that because TOML does not adhere to a tree structure, the `required` and `ignored` fields must be declared before any `[[constraint]]` or `[[override]]`.
There is a full [example](#example) `Gopkg.toml` file at the bottom of this document. `dep init` will also, by default, generate a `Gopkg.toml` containing some example values, for guidance.
## Dependency rules: `[[constraint]]` and `[[override]]`
Most of the rule declarations in a `Gopkg.toml` will be either `[[constraint]]` or `[[override]]` stanzas. Both of these types of stanzas allow exactly the same types of values, but dep interprets them differently. Each allows the following values:
* `name` - the import path corresponding to the [source root](glossary.md#source-root) of a dependency (generally: where the VCS root is)
* At most one [version rule](#version-rules)
* An optional [`source` rule](#source)
* [`metadata`](#metadata) that is specific to the `name`'d project
A full example (invalid, actually, as it has more than one version rule, for illustrative purposes) of either one of these stanzas looks like this:
```toml
[[constraint]]
# Required: the root import path of the project being constrained.
name = "github.com/user/project"
# Recommended: the version constraint to enforce for the project.
# Note that only one of "branch", "version" or "revision" can be specified.
version = "1.0.0"
branch = "master"
revision = "abc123"
# Optional: an alternate location (URL or import path) for the project's source.
source = "https://github.com/myfork/package.git"
# Optional: metadata about the constraint or override that could be used by other independent systems
[metadata]
key1 = "value that convey data to other systems"
system1-data = "value that is used by a system"
system2-data = "value that is used by another system"
```
### `[[constraint]]`
A `[[constraint]]` stanza defines rules for how a [direct dependency](glossary.md#direct-dependency) must be incorporated into the dependency graph. Dep respects these declarations from the current project's `Gopkg.toml`, as well as the `Gopkg.toml` files found in any dependencies.
**Use this for:** having a [direct dependency](FAQ.md#what-is-a-direct-or-transitive-dependency) use a specific branch, version range, revision, or alternate source (such as a fork).
### `[[override]]`
An `[[override]]` stanza differs from a `[[constraint]]` in that it applies to all dependencies, [direct](glossary.md#direct-dependency) and [transitive](glossary.md#transitive-dependency), and supersedes all other `[[constraint]]` declarations for that project. However, only overrides from the current project's `Gopkg.toml` are incorporated.
**Use this for:** Overrides are primarily intended as a way of eliminating disagreements between multiple irreconcilable `[[constraint]]` declarations on a single dependency. However, they will also be your primary recourse if you need to [constrain a transitive dependency's version?](FAQ.md#how-do-i-constrain-a-transitive-dependencys-version)
Overrides should be used cautiously and temporarily, when possible.
### `source`
A `source` rule can specify an alternate location from which the `name`'d project should be retrieved. It is primarily useful for temporarily specifying a fork for a repository.
`source` rules are generally brittle and should only be used when there is no other recourse. Using them to try to circumvent network reachability issues is typically an antipattern.
### Version rules
Version rules can be used in either `[[constraint]]` or `[[override]]` stanzas. There are three types of version rules - `version`, `branch`, and `revision`. At most one of the three types can be specified.
#### `version`
`version` is a property of `constraint`s and `override`s. It is used to specify version constraint of a specific dependency. It can be used to target an arbitrary VCS tag, or a semantic version, or a range of semantic versions.
Specifying semantic version ranges can be done using the following operators:
* `=`: equal
* `!=`: not equal
* `>`: greater than
* `<`: less than
* `>=`: greater than or equal to
* `<=`: less than or equal to
* `-`: literal range. Eg: 1.2 - 1.4.5 is equivalent to >= 1.2, <= 1.4.5
* `~`: minor range. Eg: ~1.2.3 is equivalent to >= 1.2.3, < 1.3.0
* `^`: major range. Eg: ^1.2.3 is equivalent to >= 1.2.3, < 2.0.0
* `[xX*]`: wildcard. Eg: 1.2.x is equivalent to >= 1.2.0, < 1.3.0
You might, for example, include a rule that specifies `version = "=2.0.0"` to pin a dependency to version 2.0.0, or constrain to minor releases with: `version = "~2.1.0"`. Refer to the [semver library](https://github.com/Masterminds/semver) documentation for more info.
**Note**: When you specify a version *without an operator*, `dep` automatically uses the `^` operator by default. `dep ensure` will interpret the given version as the min-boundary of a range, for example:
* `1.2.3` becomes the range `>=1.2.3, <2.0.0`
* `0.2.3` becomes the range `>=0.2.3, <0.3.0`
* `0.0.3` becomes the range `>=0.0.3, <0.1.0`
`~` and `=` operators can be used with the versions. When a version is specified without any operator, `dep` automatically adds a caret operator, `^`. The caret operator pins the left-most non-zero digit in the version. For example:
```
^1.2.3 means 1.2.3 <= X < 2.0.0
^0.2.3 means 0.2.3 <= X < 0.3.0
^0.0.3 means 0.0.3 <= X < 0.1.0
```
To pin a version of direct dependency in manifest, prefix the version with `=`. For example:
```toml
[[constraint]]
name = "github.com/pkg/errors"
version = "=0.8.0"
```
#### `branch`
Using a `branch` constraint will cause dep to use the named branch (e.g., `branch = "master"`) for a particular dependency. The revision at the tip of the branch will be recorded into `Gopkg.lock`, and almost always remain the same until a change is requested, via `dep ensure -update`.
In general, you should prefer semantic versions to branches, when a project has made them available.
#### `revision`
A `revision` is the underlying immutable identifier - like a git commit SHA1. While it is allowed to constrain to a `revision`, doing so is almost always an antipattern.
Usually, folks are inclined to pin to a revision because they feel it will somehow improve their project's reproducibility. That is not a good reason. `Gopkg.lock` provides reproducibility. Only use `revision` if you have a good reason to believe that _no_ other version of that dependency _could_ work.
## Package graph rules: `required` and `ignored`
As part of normal operation, dep analyzes import statements in Go code. These import statements connect packages together, ultimately forming a graph. The `required` and `ignored` rules manipulate that graph, in ways that are roughly dual to each other: `required` adds import paths to the graph, and `ignored` removes them.
### `required`
`required` lists a set of packages (not projects) that must be included in Gopkg.lock. This list is merged with the set of packages imported by the current project.
```toml
required = ["github.com/user/thing/cmd/thing"]
```
**Use this for:** linters, generators, and other development tools that
* Are needed by your project
* Aren't `import`ed by your project, [directly or transitively](FAQ.md#what-is-a-direct-or-transitive-dependency)
* You don't want to put them in your `GOPATH`, and/or you want to lock the version
Please note that this only pulls in the sources of these dependencies. It does not install or compile them. So, if you need the tool to be installed you should still run the following (manually or from a `Makefile`) after each `dep ensure`:
```bash
cd vendor/pkg/to/install
go install .
```
This only works reliably if this is the only project to install these executables. This is not enough if you want to be able to run a different version of the same executable depending on the project you're working. In that case you have to use a different `GOBIN` for each project, by doing something like this before running the above commands:
```bash
export GOBIN=$PWD/bin
export PATH=$GOBIN:$PATH
```
You might also try [virtualgo](https://github.com/GetStream/vg), which installs dependencies in the `required` list automatically in a project specific `GOBIN`.
### `ignored`
`ignored` lists a set of packages (not projects) that are ignored when dep statically analyzes source code. Ignored packages can be in this project, or in a dependency.
```toml
ignored = ["github.com/user/project/badpkg"]
```
Use `*` to define a package prefix to be ignored. This will cause any lexical wildcard match to be ignored, including the literal string prior to the `*`.
```toml
ignored = ["github.com/user/project/badpkg*"]
```
**Use this for:** preventing a package, and any of that package's unique dependencies, from being incorporated in `Gopkg.lock`.
## `metadata`
`metadata` can exist at the root as well as under `constraint` and `override` declarations.
`metadata` declarations are ignored by dep and are meant for usage by other independent systems.
The root `metadata` declaration defines information about the project itself, while a `metadata` declaration under a `[[constraint]]` or an `[[override]]` defines metadata about that rule, for the `name`d project.
```toml
[metadata]
key1 = "value that convey data to other systems"
system1-data = "value that is used by a system"
system2-data = "value that is used by another system"
```
## `prune`
`prune` defines the global and per-project prune options for dependencies. The options determine which files are discarded when writing the `vendor/` tree.
The following are the current available options:
* `unused-packages` indicates that files from directories that do not appear in the package import graph should be pruned.
* `non-go` prunes files that are not used by Go.
* `go-tests` prunes Go test files.
Out of an abundance of caution, dep non-optionally preserves files that may have legal significance.
Pruning is disabled by default. It can be enabled by setting them to `true` at the root level.
```toml
[prune]
non-go = true
```
The same prune options can be defined per-project. An addtional `name` field is required and, as with should represent a project and not a package.
```toml
[prune]
non-go = true
[[prune.project]]
name = "github.com/project/name"
go-tests = true
non-go = false
```
# Example
A sample `Gopkg.toml` with most elements present:
```toml
required = ["github.com/user/thing/cmd/thing"]
ignored = [
"github.com/user/project/pkgX",
"bitbucket.org/user/project/pkgA/pkgY"
]
[metadata]
codename = "foo"
[prune]
non-go = true
[[prune.project]]
name = "github.com/project/name"
go-tests = true
non-go = false
[[constraint]]
name = "github.com/user/project"
version = "1.0.0"
[metadata]
property1 = "value1"
property2 = 10
[[constraint]]
name = "github.com/user/project2"
branch = "dev"
source = "github.com/myfork/project2"
[[override]]
name = "github.com/x/y"
version = "2.4.0"
[metadata]
propertyX = "valueX"
```