文章目录
  1. 1. godep
  2. 2. govendor
  3. 3. glide
  4. 4. 总结

golang1.5版本开始支持第三方包到依赖管理,当多个项目在同一个GOPATH下,每个项目包含到第三方包通过go get命令都会getGOPATH下到src目录中,而不是各个项目的文件夹中,这就导致第三方包的不同版本不能同时被GOPATH下到多个项目使用,从golang需要设置GOPATH来看,golang其实把每个项目当作一个个独立的第三包来看待。

关于golang包管理工具的topic, 在golang的官方wiki要有一篇总结对比的文章:PackageManagementTools。下面主要就项目中用过的godep,govendor,glide做一个简要的对比分析。

godep

godep helps build packages reproducibly by fixing their dependencies.

前置条件

  • 项目处在GOPATH
  • 项目能被go install通过
  • 项目能被go test通过

包初始化管理
在项目根目录下执行godep save命令

1
$ godep save

会在项目根目录下生成两个文件夹:

Godeps目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
➜  Godeps tree
.
├── Godeps.json
└── Readme

0 directories, 2 files
➜ Godeps cat Godeps.json
{
"ImportPath": "yaml",
"GoVersion": "go1.6",
"GodepVersion": "v70",
"Packages": [
"./..."
],
"Deps": [
{
"ImportPath": "gopkg.in/yaml.v2",
"Rev": "a83829b6f1293c91addabc89d0571c246397bbf4"
}
]
}

vendor目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
➜  vendor tree
.
└── gopkg.in
└── yaml.v2
├── apic.go
├── decode.go
├── emitterc.go
├── encode.go
├── LICENSE
├── LICENSE.libyaml
├── parserc.go
├── readerc.go
├── README.md
├── resolve.go
├── scannerc.go
├── sorter.go
├── writerc.go
├── yaml.go
├── yamlh.go
└── yamlprivateh.go

2 directories, 16 files

可以看到,godep把第三包的版本依赖信息记录在Godeps.json下,并且把第三包完整拷贝一份到vendor下面。通过对Godeps.json文件进行版本管理即可以管理整个项目的第三方包依赖信息。

添加新包
方法一:

go get 把新增的第三方包get到GOPATHsrc目录下,然后再执行godep save

方法二:

godep get 同样是把第三方包get到GOPATHsrc下,然后再执行godep save

可以看到godep只是把第三方包进行单独到依赖管理,而新增到第三包还是会被get到GOPATH中, 如果多个项目用同一个第三包的不同版本时,显然不能满足。

更新包
godep通过godep update 更新制定的第三包以及golang的版本。

govendor

govendor Uses the go1.5+ vendor folder. Multiple workflows supported, single tool.

Quick Start

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Setup your project.
cd "my project in GOPATH"
govendor init

# Add existing GOPATH files to vendor.
govendor add +external

# View your work.
govendor list

# Look at what is using a package
govendor list -v fmt

# Specify a specific version or revision to fetch
govendor fetch golang.org/x/net/context@a4bbce9fcae005b22ae5443f6af064d80a6f5a55
govendor fetch golang.org/x/net/context@v1 # Get latest v1.*.* tag or branch.
govendor fetch golang.org/x/net/context@=v1 # Get the tag or branch named "v1".

# Update a package to latest, given any prior version constraint
govendor fetch golang.org/x/net/context

Sub-commands

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
init     Create the "vendor" folder and the "vendor.json" file.
list List and filter existing dependencies and packages.
add Add packages from $GOPATH.
update Update packages from $GOPATH.
remove Remove packages from the vendor folder.
status Lists any packages missing, out-of-date, or modified locally.
fetch Add new or update vendor folder packages from remote repository.
sync Pull packages into vendor folder from remote repository with revisions
from vendor.json file.
migrate Move packages from a legacy tool to the vendor folder with metadata.
get Like "go get" but copies dependencies into a "vendor" folder.
license List discovered licenses for the given status or import paths.
shell Run a "shell" to make multiple sub-commands more efficent for large
projects.

go tool commands that are wrapped:
`+<status>` package selection may be used with them
fmt, build, install, clean, test, vet, generate

Status

1
2
3
4
5
6
7
8
9
10
11
12
+local    (l) packages in your project
+external (e) referenced packages in GOPATH but not in current project
+vendor (v) packages in the vendor folder
+std (s) packages in the standard library

+unused (u) packages in the vendor folder, but unused
+missing (m) referenced packages but not found

+program (p) package is a main package

+outside +external +missing
+all +all packages

可以看到govendor init之后会在根目录下生成一个vendor文件夹

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
➜  yaml tree -d
.
└── vendor
├── github.com
│   └── cihub
│   └── seelog
└── gopkg.in
└── yaml.v2

6 directories
➜ yaml cat vendor/vendor.json
{
"comment": "",
"ignore": "test",
"package": [
{
"checksumSHA1": "Nc93Ubautl47L3RP6x4lTY+ud68=",
"path": "github.com/cihub/seelog",
"revision": "cedd97ac8c6c2ec413a97864185f9510fb1775cc",
"revisionTime": "2016-05-20T13:10:56Z"
},
{
"checksumSHA1": "+OgOXBoiQ+X+C2dsAeiOHwBIEH0=",
"path": "gopkg.in/yaml.v2",
"revision": "a83829b6f1293c91addabc89d0571c246397bbf4",
"revisionTime": "2016-03-01T20:40:22Z"
}
],
"rootPath": "yaml"
}

govendor fetch <url1> <url2>新增的第三方包直接被get到根目录的vendor文件夹下,不会与其它的项目混用第三方包,完美避免多个项目同用同一个第三方包的不同版本问题。

只需要对vendor/vendor.json进行版本控制,即可对第三包依赖关系进行控制。

glide

Glide Vendor Package Management for Golang.

Usage

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
➜  yaml glide --help
USAGE:
glide [global options] command [command options] [arguments...]

create, init Initialize a new project, creating a glide.yaml file
get Install one or more packages into `vendor/` and add dependency to glide.yaml.
remove, rm Remove a package from the glide.yaml file, and regenerate the lock file.
import Import files from other dependency management systems.
name Print the name of this project.
novendor, nv List all non-vendor paths in a directory.
rebuild Rebuild ('go build') the dependencies
install, i Install a project's dependencies
update, up Update a project's dependencies
tree Tree prints the dependencies of this project as a tree.
list List prints all dependencies that the present code references.
info Info prints information about this project
about Learn about Glide

GLOBAL OPTIONS:
--yaml, -y "glide.yaml" Set a YAML configuration file.
--quiet, -q Quiet (no info or debug messages)
--debug Print Debug messages (verbose)
--home "/home/dev/.glide" The location of Glide files [$GLIDE_HOME]
--no-color Turn off colored output for log messages
--help, -h show help
--version, -v print the version

glide 通过glide createglide init命令初始化第三方包管理,会在项目根目录下生成一个glide.yaml,这个文件记录用到的第三方包的依赖关系,支持编辑修改。
glide通过glide install, 会把所有缺少的第三方包都下载到vendor文件夹下,并且会在glide.yaml中添加所有依赖的第三方包名称,在glide.lock文件中记录具体的版本管理信息。

glide install

When you want to install the specific versions from the glide.lock file use glide install.

1
$ glide install

This will read the glide.lock file and install the commit id specific versions there.

When the glide.lock file doesn’t tie to the glide.yaml file, such as there being a change, it will provide a warning. Running glide up will recreate the glide.lock file when updating the dependency tree.

If no glide.lock file is present glide install will perform an update and generate a lock file.

总结

  • godep,govendor,glide 都可以很好的进行包管理。govendor,glide提供的可操作命令更丰富。
  • godep 会在根目录生成Godepsvendor两个文件夹; govendor把所有信息都生成在vendor目录下; glide 会在根目录下生成glide.yaml, glide.lock文件及vendor目录; 从简洁度尽量不污染项目来看,govendor最优,glide次之。
  • godep, govendor, glide 都提供get 第三方包的命令,但是 glideglide install 最为方便, 并且直接把第三方包get到本项目的vendor目录下,并且glide提供的便捷命令也丰富。

  • 在生产项目中推荐使用govendor, 更简洁; 在试验项目中推荐试用glide, 更方便。

作者署名:朴实的一线攻城狮
本文标题:Go Vendoring Tools 使用总结
本文出处:http://researchlab.github.io/2016/05/24/comparison-of-Go-Vendoring-Tools/
版权声明:本文由Lee Hong创作和发表,采用署名(BY)-非商业性使用(NC)-相同方式共享(SA)国际许可协议进行许可,转载请注明作者及出处, 否则保留追究法律责任的权利。

@一线攻城狮

关注微信公众号 @一线攻城狮

总访问:
总访客: