go 依赖包升级方法
在维护一个有一定体量的 go 项目的时候,难免会碰到需要依赖包管理的问题。关于 go 的依赖包管理有很多不错的文章介绍How to Use Go Modules,这篇文章总结的是项目于中 go mod 依赖包升级的问题。
背景
go 项目中使用 go mod vendor
来离线管理所有的依赖包(主要是出于依赖版本锁定的目的),在项目日常管理中会涉及到几个跟依赖包升级的场景:
- 公共依赖包升级
- 私有依赖包升级
下面我们就分这两个场景来讨论。
公共依赖包升级
公共开源的依赖包升级相对比较简单,在 go 项目下执行:go get -u github.com/xxx/xxx
更细致的还会有如下几种方式升级:
- 升级到指定版本:
go get -u github.com/xxx/xxx@v1.6.2
- 升级到指定 commit 的版本:
go get github.com/xxxx/xxx@q2516faf3
私有依赖包升级
升级私有库的方法逻辑跟公共依赖包是一致的,不过我在具体操作的时候踩了一个坑:
go: downloading gitlab.com/xxx v0.1.0 verifying gitlab.com/xxx@v0.1.0: github.com/alessiosavi/GoGPUtils@v0.0.9: reading https://sum.golang.org/lookup/gitlab.com/xxx@v0.1.0: 410 Gone
解决的方法是对环境变量进行设置(410 gone during go.mod import · Issue #35164 · golang/go):
go env -w GO111MODULE=on
go env -w GOPROXY=direct
go env -w GOSUMDB=off
前两个设置比较好理解:
GO111MODULE
启用 go moduleGOPROXY
module 托管站点代理
而真正导致私有模块有 410 Gone
报错的主要原是第三个 GOSUMDB
,go module 启用时在本地建立一个 go.sum
文件,用来存储依赖包特定版本的加密校验值。同时,go 维护下载的软件包的缓存,并在下载时计算并记录每个软件包的加密校验值。在正常操作中,go 命令对照这些预先计算的校验和去检查某 repo 下的 go.sum
文件,而不是在每次命令调用时都重新计算它们。特定 module 版本的校验值永远不会改变,所以每次运行或构建时 go 命令都会通过本地的go.sum
去检查其本地缓存副本的校验值是否一致。如果校验值不匹配,则 go 命令将报告安全错误,并拒绝运行构建或运行。在这种情况下,重要的是找出正确的校验值,确定是 go.sum
错误还是下载的代码是错误的。如果 go.sum
中尚未包含已下载的module,并且该模块是公共 module,则 go 命令将查询 go 校验值数据库以获取正确的校验和数据存入 go.sum
。如果下载的代码与校验值不匹配,则 go 命令将报告不匹配并退出。
go 1.13 提供了 GOSUMDB
环境变量用于配置 go 校验值数据库的服务地址(和公钥),其默认值为”sum.golang.org”,这也是 go 官方提供的校验值数据库服务(国内也可以使用sum.golang.google.cn,你懂的)。
根据 GOSUMDB
的原理接可以知道私有库的校验值在 GOSUMDB
中肯定是没有,这就导致了出现找不到的问题即 410 Gone
报错。所以一个快速的修复的方法就是关闭 GOSUMDB
。