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
andoverrides
allow the user to specify which versions of dependencies are acceptable, and where they should be retrieved from. - Package graph rules:
required
andignored
allow the user to manipulate the import graph by including or excluding import paths, respectively. 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
settings determine what files and directories can be deemed unnecessary, and thus automatically removed fromvendor/
.noverify
is a list of project roots for which vendor verification is skipped.
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 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.
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 of a dependency (generally: where the VCS root is)- At most one version rule
- An optional
source
rule metadata
that is specific to thename
'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:
[[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"
A [[constraint]]
stanza defines rules for how a 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 use a specific branch, version range, revision, or alternate source (such as a fork).
An [[override]]
stanza differs from a [[constraint]]
in that it applies to all dependencies, direct and transitive, 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?
Overrides should be used cautiously and temporarily, when possible.
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 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
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. E.g., 1.2 - 1.4.5 is equivalent to >= 1.2, <= 1.4.5~
: minor range. E.g., ~1.2.3 is equivalent to >= 1.2.3, < 1.3.0^
: major range. E.g., ^1.2.3 is equivalent to >= 1.2.3, < 2.0.0[xX*]
: wildcard. E.g., 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 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:
[[constraint]]
name = "github.com/pkg/errors"
version = "=0.8.0"
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.
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.
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
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.
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 - 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
:
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:
export GOBIN=$PWD/bin
export PATH=$GOBIN:$PATH
You might also try virtualgo, which installs dependencies in the required
list automatically in a project specific GOBIN
.
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.
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 *
.
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
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.
[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
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 options are disabled by default. However, generating a Gopkg.toml
via dep init
will add lines to enable go-tests
and unused-packages
prune options at the root level.
[prune]
go-tests = true
unused-packages = true
The same prune options can be defined per-project. An additional name
field is required and, as with [[constraint]]
and [[override]]
, should be a source root, not just any import path.
[prune]
non-go = true
[[prune.project]]
name = "github.com/project/name"
go-tests = true
non-go = false
Almost all projects will be fine without setting any project-specific rules, and enabling the following pruning rules globally:
[prune]
unused-packages = true
go-tests = true
It is usually safe to set non-go = true
, as well. However, as dep only has a clear model for the role played by Go files, and non-Go files necessarily fall outside that model, there can be no comparable general definition of safety.
The noverify
field is a list of paths, typically project roots, to exclude from vendor verification.
Dep uses per-project hash digests, computed after pruning and recorded in Gopkg.lock, to determine if the contents of vendor/
are as expected. If the recorded digest and the hash of the corresponding tree in vendor/
differ, that project is considered to be out of sync:
dep ensure
will regenerate itdep check
will complain of a hash mismatch and exit 1
It is strongly recommended that you leave vendor/
unmodified, in whatever state dep puts it in. However, this isn't always feasible. If you have no choice but to modify vendor/
for a particular project, then add the project root for that project to noverify
. This will have the following effects:
dep ensure
will ignore hash mismatches for the project, and only regenerate it invendor/
if absolutely necessary (prune options change, package list changes, version changes)dep check
will continue to report hash mismatches (albeit with an annotation aboutnoverify
) for the project, but will no longer exit 1.
noverify
can also be used to preserve certain excess paths that would otherwise be removed; for example, adding WORKSPACE
to the noverify
list would allow you to preserve vendor/WORKSPACE
, which can help with some Bazel-based workflows.
dep
evaluates
[[override]]
required
ignored
only in the root project, i.e. the project where dep
runs. For example, if you have a project: github.com/urname/goproject
, and github.com/foo/bar
is a dependency for your project, then dep will evaluate the Gopkg.toml
files of these projects as follows:
github.com/urname/goproject | github.com/foo/bar |
---|---|
[[constraint]] ✔ | [[constraint]] ✔ |
[[override]] ✔ | [[override]] ✖ |
required ✔ | required ✖ |
ignored ✔ | ignored ✖ |
✔ : Evaluated ✖ : Not evaluated
Here's a sample Gopkg.toml
with most elements present.
required = ["github.com/user/thing/cmd/thing"]
ignored = [
"github.com/user/project/pkgX",
"bitbucket.org/user/project/pkgA/pkgY"
]
noverify = ["github.com/something/odd"]
[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"
[constraint.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"
[override.metadata]
propertyX = "valueX"