golang 官方依赖管理工具 dep 使用和持续集成

[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
官方文档地址 https://golang.github.io/dep/docs/introduction.html

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.lockGopkg.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

dep ensure -add 添加依赖后,没有在 vendor 目录中,是因为需要在代码中用到这个库才能正确添加
所以在执行 dep ensure -add 后,先尝试使用一下新添加的库,然后运行 dep ensure -v

依赖查看

可以使用 dep status 查看当前工程的依赖

$ dep status
PROJECT CONSTRAINT VERSION REVISION LATEST PKGS USED
golang.org/x/net branch master branch master 461777f 3f473d3 4
golang.org/x/sys branch master branch master 93c9922 93c9922 2
golang.org/x/text v0.3.2 v0.3.2 342b2e1 v0.3.2 17
golang.org/x/tools branch master branch master f8d1dee d4e310b 4
gopkg.in/go-playground/validator.v8 v8.18.2 v8.18.2 5f1438d v8.18.2 1
gopkg.in/yaml.v2 v2.2.2 v2.2.2 51d6538 v2.2.2 1
$ dep status | grep gin
github.com/gin-contrib/sse v0.1.0 v0.1.0 54d8467 v0.1.0 1
github.com/gin-gonic/gin ^1.4.0 v1.4.0 b75d67c v1.4.0 4
github.com/swaggo/gin-swagger branch master branch master dbf6ef4 ddb1576 2
  • 如果需要依赖图查看,可以借助 graphviz 工具
# linux 设备
$ sudo apt-get install graphviz
$ dep status -dot | dot -T png | display
# macOS
$ brew install graphviz
$ dep status -dot | dot -T png | open -f -a /Applications/Preview.app
# windows 先安装 chocolatey https://chocolatey.org/
> choco install graphviz.portable
> dep status -dot | dot -T png -o status.png; start status.png

依赖约束规则

添加依赖常用的用法是

# 依赖指定的版本 0.4.3
dep ensure -add github.com/bitly/go-simplejson@=0.4.3
# 依赖大于等于 0.4.3 的版本
dep ensure -add github.com/bitly/go-simplejson@^0.4.3

-add 时可用的规则详细说明见, https://golang.github.io/dep/docs/ensure-mechanics.html#add

依赖更新的规则,常见约束见表

GOPKG.TOML 版本约束类型 例子 dep ensure -update 行为
version (语义化版本) "^1.0.0" 试图获得最新可用版本
branch "master" 试图切换到这个分支最新提交
version (非限定语义版本) "=1.0.0" 只在多个版本时才更新依赖到指定版本 (e.g. git push --force <tag>)
version (非语义版本) "foo" 只在多个版本时才更新依赖版本
revision aabbccd... 不会更改依赖
(none) (none) 根据第一个版本来,参见 依赖排序文档 the sort order

-update 的规则,详细文档见 https://golang.github.io/dep/docs/ensure-mechanics.html#update

依赖更新

编辑 Gopkg.toml 文件,配置新的依赖,然后执行

dep ensure -update -v && dep ensure -v

注意,这个和更新依赖是完全不同的概念,因为 dep 依赖 vendor 目录,所以会出现一种奇怪的情况
toml 文件修改了,但是依赖没有在 vendor 目录出现,这点你需要学习 node_module 修复大法
删除 vendor 目录中对应的内容,或者干掉整个 vendor 目录

参考 https://golang.github.io/dep/docs/failure-modes.html#vendor-write-errors

依赖管理缓存错误

dep 的依赖管理会使用本地缓存,缓存目录是 $GOPATH/pkg/dep/sources
出现某些版本冲突问题时,可以删除这个缓存来解决问题

参考 https://golang.github.io/dep/docs/failure-modes.html#bad-local-cache-state

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.tomlGopkg.lock 全部 vendor 目录都提交,git 仓库压力很大,但是可以做到减少远程依赖

这种方式可以做到开箱即用

  • 让工程只保留 Gopkg.tomlGopkg.lock,减少仓库代码大小,降低仓库压力

这种方式,每次构建就得执行 dep ensure -v

我倾向于选择提交全部 vendor, 原因是远程仓库的依赖拉取非常慢,容易拖慢构建
如果git 仓库压力很大,可以做缓存仓库迁移分离压力,当然得写脚本批量修改 golang 代码的引用

当然你还有一个选择,将 vendor 做成一个共享目录,编译时挂载到编译工程,这样既让 git 仓库的压力变小,也不被远程仓库网速问题困扰,缺点就是得额外维护脚本

构建过程的控制

  • 因为 ${GOPATH} 环境变量的特殊性,不建议直接使用类似 jenkins 这种虚拟命令行构建,容易导致各种混乱(复数GOPATH,虽然可行,但存在环境串扰,降低编译速度,甚至报错的问题)
  • 使用 docker 临时容器构建,输出构建的目标二进制和报告作为结果是最好的选择
  • 如果是服务型的构建,可以直接使用 docker 容器编排测试服务

docker容器服务构建样例 https://github.com/bridgewwater/docker-beego-temple

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,780评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,424评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,397评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,576评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,997评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,945评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,107评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,850评论 0 208
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,625评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,804评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,285评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,613评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,291评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,164评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,963评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,096评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,886评论 2 278

推荐阅读更多精彩内容

  • 依赖管理是一个语言非常重要的特性,很大程度上决定着一个语言的流行程度,流行的语言大多都有非常成熟的依赖管理工具,j...
    hatlonely阅读 303评论 0 1
  • [TOC] 介绍 godep是解决包依赖的管理工具,目前最主流的一种,原理是扫描记录版本控制的信息,并在go命令前...
    木猫尾巴阅读 17,437评论 0 7
  • 1. 分布式系统核心问题 参考书籍:《区块链原理、设计与应用》 一致性问题例子:两个不同的电影院买同一种电影票,如...
    molscar阅读 874评论 0 0
  • Go入门 Go介绍 部落图鉴之Go:爹好还这么努力? 环境配置 安装 下载源码编译安装 下载相应平台的安装包安装 ...
    齐天大圣李圣杰阅读 4,537评论 0 26
  • 陳主管原本管理著A/B/C三個部門,前段时间會議后老闆講A/B部門劃給他人管理,陳主管僅管C部門.這一整天陳主管都...
    赵秋视点阅读 132评论 0 1