Go Modules 常见使用陷阱

Go Modules 是 Go 官方推出的依赖管理工具,Go Modules 的使用可以参见我之前翻译的官方博客

Go Modules 在使用的过程中还是会有一些坑,这篇文章将会介绍一些我踩过的坑。

1. Go mod 命令详解

在 Go 中,提供了 go mod 命令来使用 Go Modules,可以通过 go help mod 来查看支持的命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ go help mod

# 使用方式
go mod <command> [arguments]

# commands
download # 将远程的包下载到本地缓存中
edit # 编辑 go.mod 文件,其实使用编辑器编辑会更方便
graph # 查看所有依赖的关系
init # 用来创建一个使用 Go Modules 的项目
tidy # 添加缺失的包,以及移除不再使用的包
vendor # 将依赖的包拷贝到项目的 vendor 目录下
verify # 验证依赖包与预期的一致
why # 解释为什么需要这个包

go mod download 会将依赖缓存到本地,缓存的目录是 $GOPATH/pkg/mod/cache,这些被缓存的依赖可以被多个项目使用。

go mod graph 可以用来查看项目的依赖,但看起来不是很直观,希望后续能够继续改进。

go mod init 和 go mod tidy 最常用,分别用来初始化一个 Go Modules 以及添加和删除无用的依赖。

go mod vendor 可以将项目的依赖打包放到当前项目的根目录下,这样可以防止项目的依赖被修改。

go mod verify 和 go mod why 相对来说用的就比较少。

2. 如何获取新的依赖

在使用了 Go Modules 以后,go get 依然是获取依赖常用的方法。

使用也很简单:

1
go get github.com/rayjun/go-mod-demo

这样会直接去拉取 go-mod-demo 的最新 tag,如果没有 tag,就会去拉取最新一次 commit。

也可以直接去拉取某个指定的分支,下面的命令会拉取分支 v1.0.1 的代码:

1
go get github.com/rayjun/go-mod-demo@v1.0.1

如果 tag 和分支同名时,会优先去拉取 tag 下的代码,一般情况下,不要让 tag 和分支同名,而且同名会导致推送代码到分支失败。

在一些情况下,我们可以需要删除 tag 名,更新代码后再使用这个相同的 tag 名,这样就会导致之前已经下载了这些代码的人无法获取到最新的代码,所以需要先清空本地的缓存,然后再重新下载依赖:

1
2
go clean --modcache # 将本地缓存的所有依赖都清空
go get -u github.com/rayjun/go-mod-demo@v1.0.1 # 获取最新的代码

3. Go Modules 中的版本号

Go Modules 使用的是语义版本号来实现对代码版本的管理,语义版本号由三个部分组成:

1
MAJOR.MINOR.PATCH # 主版本号.次版本号.补丁版本号

在一些情况下,还可以配置 alpha 等来表示一些先行版本:

1
v1.0.2-alpha.1

每个 Go Modules 都应该使用这样的版本号来管理代码。如果出现了 v1.0.2.1 这样的版本号,Go Modules 就无法识别:

1
go get -u github.com/rayjun/go-mod-demo@v1.0.2.1

实际在 go.mod 中显示的版本号是这样的:

1
github.com/rayjun/go-mod-demo v1.0.3-0.20210327072248-86af6328b20f

对于一个良好的 Go Modules,应该使用 master 分支 + 多 tag 的形式来管理代码,意思就是 master 保持最新的代码,然后每一个已经发布的代码使用 tag 的形式发布出来。tag 的版本号应该符合语义版本号的规则。

文/Rayjun

© 2020 Rayjun    PowerBy Hexo    京ICP备16051220号-1