Gopkg.toml是在执行dep init时创建,主要被手动编辑,可以使用以下规则声明方式来改变dep的行为:
- 允许使用
constraints
和overrides
指定可以接受的版本,以及指定获取来源(比如指定依赖的某个第三方库为特定版本号) - 允许使用
required
andignored
来分别增加或排除import路径,进而操纵import graph(允许在go/src之外存放依赖) - 允许使用
metadata
来定义key-value元数据,dep会忽略这些数据,为在dep之上的构建工具链提供支持(CI/自动化编译/自动化部署/自动化测试等流程) prune
可以用来定义哪些文件或路径被认为是不必要的,也就是说可以从vendor中移除(也就是说保持vendor精简)noverify
用来指定vendor verification需要跳过的一系列的项目路径。
要注意的是,任何required,或者ignored字段,必须出现在所有的[[constraint]]以及[[override]]之前
依赖规则[[constraint]]
and [[override]]
都用来描述依赖,区别是[[override]]要谨慎使用。它会用当前项目中的override(如果当前项目依赖的包里面还有override,则会忽略其指定的override),而constraint不一样
。
二者都允许包含如下字段
name
- the import path corresponding to the source root of a dependency (generally: where the VCS root is)
版本规则
可选的source rule
metadata
source
用来翻墙。也就是说,为被依赖的仓库指定个候选地址。
版本号规则
[[constraint]]和[[override]]都可以指定版本号规则,可以使用version, branch, revision其中之一来指定(也只能选择一种);
version对应于VCS的tag,或者一个版本号范围(or a semantic version, or a range of semantic version):
version="=1.2.3"用来指定确切的版本号,也就是1.2.3这个版本;
version="!=1.2.3"用来排除某个版本号,也就是说只要不是1.2.3这个版本就行;
version="1.2.3-2.1.2"用来指定版本号范围;
类似还有:
>, >=, <, <=
不过,你可能没想到的还有,
version = "~1.2.3"意思是,只允许最后一段版本号变化;
version = "^1.2.3"意思是,除了非0的最大的一段版本号不允许变化,后面的版本号都可以变化;
^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
另外还允许通配符(肯定脑子进水了,才这样去做事情)。
所以,要想锁定一个版本号,你要这样做:
[[constraint]]
name = "github.com/pkg/errors"
version = "=0.8.0"
有时候,有些仓库不会使用version,而是使用branch。语法是:
branch="feature_support_dynamic_routing"
然而,如果你指定branch="master"不是个好主意。因为master从来不意味着不再改变。
一般情况下,应该优先使用语义上的版本(you should prefer semantic versions to branches, when a project has made them available),而不是branch。
revision是底层的不可变的标识符,就像git commit的sha1. (While it is allowed to constrain to a revision
, doing so is almost always an antipattern)
老夫看的萌萌的,一句话就是尽量别用revision来约束。
required
and ignored
分别用来增加或排除import路径,进而操纵import graph(允许在go/src之外存放依赖)
required
用来列举包列表(而不是project),列出的包必须包含在 Gopkg.lock里(Gopkg.lock里还会包含被当前项目import的包)。
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
用来指定dep静态分析代码生成Gopkg.lock时需要忽略的包列表(如果包依赖了其他包X,并且X包只在这里被依赖,那么X也将被忽略),注意这里说的包可以是dependency中的包。ignored = ["github.com/user/project/badpkg"]
你还是可以用通配符的:
ignored = ["github.com/user/project/badpkg*"]
metadata可以在Gopkg.toml中root级别存在,也可以在constraint, override中存在。
dep会假装看不见metadata.
prune用来指定全局,或者按照project范围精简依赖(默认不采用任何策略)。它将指导在写vendor目录时,哪些文件可以被discard,当前可以用以下定义:
unused-packages
:没有被import的依赖
non-go:非golang的文件
go-tests:golang的测试文件
[prune]
non-go = true
[[prune.project]]
name = "github.com/project/name"
go-tests = true
non-go = false
noverify
尽管强烈建议不要修改vendor目录,但是有时候还是有人干。noverify用来告诉dep一系列路径(典型的包括项目根目录),你进行vendor verification(检查Gopkg.lock中的数据是不是跟vendor的实际属性一致)时请忽略这些路径:
dep ensure
will ignore hash mismatches for the project, and only regenerate it in vendor/
if absolutely necessary (prune options change, package list changes, version changes)
dep check
will continue to report hash mismatches (albeit with an annotation about noverify
) for the project, but will no longer exit 1.
Scope
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
Example
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"