[TOC]
介绍
go dep 依赖管理工具是为应用管理代码的,go get是为GOPATH管理代码的
官方地址 https://github.com/golang/dep
官方说明为啥要统一依赖管理 https://github.com/golang/dep/blob/master/docs/FAQ.md#does-dep-replace-go-get
dep 需要在Go 1.7及更高的版本中使用
安装
本文使用 golang 版本是 go1.9.3 需要自己安装 dep
go get -v -u github.com/golang/dep/cmd/dep
基础帮助参数
$ dep
Dep is a tool for managing dependencies for Go projects
Usage: "dep [command]"
Commands:
init Set up a new Go project, or migrate an existing one
status Report the status of the project's dependencies
ensure Ensure a dependency is safely vendored in the project
prune Pruning is now performed automatically by dep ensure.
version Show the dep version information
Examples:
dep init set up a new project
dep ensure install the project's dependencies
dep ensure -update update the locked versions of all dependencies
dep ensure -add github.com/pkg/errors add a dependency to the project
Use "dep help [command]" for more information about a command.
ensure 确保,确保所有本地状态-代码树、依赖列表、锁、远端oss彼此同步
使用
初始化
dep init
# 更建议使用,因为会很漫长
dep init -v
会生成两个文件 Gopkg.lock
、Gopkg.toml
和一个目录 vendor
如果报错
Gopkg.toml and Gopkg.lock are out of sync
需要执行一下dep ensure -v
其中
-
Gopkg.toml
是依赖管理的核心文件,可以生成也可以手动修改,Gopkg.toml 官方文档 -
Gopkg.lock
是生成的文件,不要手工修改 Gopkg.lock 官方文档 -
vendor
目录是 golang1.5 以后依赖管理目录,这个目录的依赖代码是优先加载的,类似 node 的node_module
目录
依赖管理
# 依赖管理帮助
dep help ensure
# 添加一条依赖
dep ensure -add github.com/bitly/go-simplejson
# 这里 @= 参数指定的是 某个 tag
dep ensure -add github.com/bitly/go-simplejson@=0.4.3
# 添加后一定记住执行 确保 同步
dep ensure
# 同理建议使用
dep ensure -v
# 更新依赖
dep ensure -update -v
# 删除没有用到的 package
dep prune -v
依赖更新
编辑 Gopkg.toml
文件,配置新的依赖,然后执行
dep ensure -update -v && dep ensure -v
注意,这个和更新依赖是完全不同的概念,因为 dep 依赖
vendor
目录,所以会出现一种奇怪的情况
toml 文件修改了,但是依赖没有在 vendor 目录出现,这点你需要学习 node_module 修复大法
删除 vendor 目录中对应的内容,或者干掉整个 vendor 目录
dep 管理存在的问题
- 远程仓库拉取会比较困难,比如 golang.org 的,这个你得自己想办法,比如使用镜像,或者把依赖扔
vendor 目录
- 因为可以发现
跨模块的代码拷贝
,导致拉取依赖失败,因为 dep 是拷贝仓库代码,报错会比较摸不到头脑,建议仔细比对日志 - 因为 go 的依赖管理实际就是 git 的仓库拉取,如果
依赖的仓库没有打 tag
, 那么dep 会使用离 HEAD 提交最近的一次 tag
导致编译经常不通过
临时解决方法是修改 Gopkg.toml
将有问题的仓库 version
注释掉,branch
切换到可以的分支
[[constraint]]
branch = "master"
name = "github.com/xx/xxx"
#version = ""
最好的方法还是给依赖仓库打 tag
持续集成使用 dep 管理依赖
这里就不介绍一个 dep 管理实例了,因为环境不一样,使用的CI CD链不一样,除了脚本可以通用,其他内容都超过了本文的范围,所以主要讲些原则上的事情
持续集成时,使用 dep 的基本原则
- 尽量
使用 tag 作为版本号
,不使用分支(tag 就是不可维护分支,能固化版本,分支没有这个能力) - 禁止非
vendor
依赖方式编译 使用 Makefile 或者 shell 控制集成过程
-
参数化部署控制
,做好 测试 灰度 生产的分离,这里推荐 viper 参数配置工具
代码提交版本管理
-
Gopkg.toml
和Gopkg.lock
全部vendor
目录都提交,git 仓库压力很大,但是可以做到减少远程依赖
这种方式可以做到开箱即用
- 让工程只保留
Gopkg.toml
和Gopkg.lock
,减少仓库代码大小,降低仓库压力
这种方式,每次构建就得执行 dep ensure -v
我倾向于选择提交全部
vendor
, 原因是远程仓库的依赖拉取非常慢,容易拖慢构建
如果git 仓库压力很大,可以做缓存仓库迁移分离压力,当然得写脚本批量修改 golang 代码的引用当然你还有一个选择,将 vendor 做成一个共享目录,编译时挂载到编译工程,这样既让 git 仓库的压力变小,也不被远程仓库网速问题困扰,缺点就是得额外维护脚本
构建过程的控制
- 因为 ${GOPATH} 环境变量的特殊性,
不建议直接使用类似 jenkins 这种虚拟命令行构建
,容易导致各种混乱(复数GOPATH,虽然可行,但存在环境串扰,降低编译速度,甚至报错的问题) - 使用 docker 临时容器构建,
输出构建的目标二进制和报告
作为结果是最好的选择 - 如果是服务型的构建,可以
直接使用 docker 容器编排测试服务
docker容器服务构建样例 https://github.com/bridgewwater/docker-beego-temple