1.语义版本机制

1.1 什么是语义版本规范

按照Go Module构建模式,一个符合Go Module要求的版本号,需要按照语义版本规范组成

语义版本规范:语义化版本 2.0.0 | Semantic Versioning

主版本号:主版本号不同的两个版本是互不兼容的

次版本号:主版本号相同的情况下,次版本号的大的,兼容次版本号小的

补丁版本号:主版本号和次版本号相同,补丁版本号大的兼容补丁版本号小的

1.2 Go Module如何使用语义版本规范

1.当新旧两个包是相互兼容的,那包的导入路径应该是相同的

eg:如果项目依赖 github.com/sirupsen/logrus 这个包,不管依赖的是这个包的v1.7.1版本还是 v1.8.1版本,包的导入路径都是

1
import github.com/sirupsen/logrus

2.如果新旧两个包不兼容,则包的导入路径不同,导入路径通过在包后面加主版本号的方式区分

eg:如果项目之前依赖github.com/sirupsen/logrus 这个包的v1.7.1,后面需要依赖 v2.7.1版本,那包的导入路径就要变为

1
import github.com/sirupsen/logrus/v2

3.如果主版本号是v0或者v1,则包的导入路径后不用跟主版本号

eg:不管项目依赖github.com/sirupsen/logrus 这个包的v0.7.1还是v1.7.1版本,包的导入路径都是

1
import github.com/sirupsen/logrus

2.Go Module的最小版本选择原则

eg:

上图的这种情况,根据Go Module的最小版本选择原则,最终会使用C v1.3.0版本,而不会使用v 1.7.0版本

原因是:对于这个项目来说C v1.3.0版本就够用了,引入更高级别的版本,虽然也可以兼容,但是增加了不稳定性

3.Go Module的6类常规操作

3.1 为当前module添加一个依赖

1.手动在源码中通过import语句导入依赖包

1
import github.com/google/uuid

2.下载依赖包并更新go.mod文件

  • 方式一:使用go get命令,下载依赖包到本地module缓存里,并更新go.mod文件
1
$go get github.com/google/uuid
  • 方式二(推荐):使用go mod tidy命令,自动检测,自动下载依赖包并更新go.mod文件

3.2 升级/降级当前依赖的版本(主版本号相同)

1.首先如果升级/降级后的依赖版本和当前版本的版本号相同,就不用修改源代码中的import导入语句

2.修改go.mod文件

  • 方式一:使用go get命令,下载升级/降级后的依赖包到本地module缓存里,并更新go.mod文件中依赖包的版本号到升级/降级后的版本
1
$go get github.com/sirupsen/logrus@v1.7.0
  • 方式二:先使用go mod edit命令,告知我们需要的升级/降级后的版本,然后再使用go mod tidy命令下载依赖包并更新go.mod文件
1
2
$go mod edit -require=github.com/sirupsen/logrus@v1.7.0
$go mod tidy

3.3 升级当前依赖版本到一个不兼容的版本

1.先修改源代码中import导入的依赖包

2.使用go get命令,下载升级后的依赖包并更新go.mod文件

3.4 添加一个主版本号大于1的依赖

1.先修改源代码中import导入的依赖包

2.使用go get命令,下载升级后的依赖包并更新go.mod文件

3.5 移除一个依赖

1.先删除源代码中import导入的依赖包

2.使用go mod tidy命令,自动分析,自动移除依赖包,自动更新go.mod文件

3.6 使用vendor机制

如果使用vendor机制,进行构建时,就会从vendor目录下拉取依赖包,而不是从GoModule的本地缓存中拉取依赖包

如果有特殊情况要使用vendor机制

1.使用go build命令构建时,需要加参数

1
$go build -mod=vendor

2.Go v1.14版本后,如果根目录下有vendor目录,则默认使用vendor机制,如果还是想使用Go Module,需要的命令如下

1
$go build -mod=mod