直接git打tag就可以发布新版本,但在发布v2以上版本时遇到了一些问题,记录一下。
(文中实际module路径均以github.com/abc/hello代替。)


还是按照老方法,直接git打tag,发布。结果在调用方就出现了问题。

更新go mod时直接报错:

require github.com/abc/hello: version “v2.x.x” invalid: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2

先说结论:
如果你是库用户,遇到这个错误,那么这属于库作者对go module特性支持不完善,请向其反馈,并参见本文中的临时解决方案一节。
如果你是库作者,如何处理这个错误,请见本文后续的高版本号(>=v2)如何良好支持go module特性一节。

库用户如何调用【未良好支持go module特性的库】的临时解决方法

库用户临时凑合调用的方法:在go.mod,import时在版本号后面加+incompatible,如

1
import github.com/abc/hello v2.0.0+incompatible

(这样仅仅是module发布者没有良好支持go module时,调用者可以采用的补丁方案)

但是这样做有缺点,
无法做到同时import多个版本。甚至在不同的文件里都不行,即使你一个文件或目录里只用了一个版本,整个项目也只能导入一份版本。
这样就不能让旧代码仍然使用旧版本,而必须整个项目一起升级到新版,所以有时会造成旧代码的破坏
同时一些IDE可能由于不识别这种版本号标识而报错。

如果我们仅仅是module的调用者而非编写者,而实际编写者又没有支持go module时,我们就可以使用这种方案临时解决调用问题。
如果我们是module的编写者,请继续看下文。

库作者发布高版本号(>=v2)如何良好支持go module特性

如果你是库作者,更完美的解决方案是:

将库的go.mod中的moulde名称后面增加版本号/vx


module github.com/abc/hello
->
module github.com/abc/hello/v2

注意,项目文件的实际结构不需要做任何改变,不需要建立v2或者vn文件夹,仅仅用于go识别主版本号。

而后重新在git中打tag v2.x.x,发布。调用方就可以愉快地使用了。

这就是module发布者根据go module特性处理版本问题的正确方法。
同时,请参照下节,更新库README以告知库用户如何正确调用新版。

库用户如何调用【有良好支持go module特性的库】的方法

库作者在正确支持go module特性后,库用户(调用方)的注意事项:

  1. go.mod中require path需要相同(结尾加上/vx)。
    require github.com/abc/hello/v2 v2.x.x
  2. 代码中的import path需要相同(结尾加上/vx)。
    import github.com/abc/hello/v2

这样,调用者可以在同一项目下import同一模块的多个主版本。
同一主版本不同子版本仍然不能共存,这是因为由golang采用的语义化版本号(Semantic Versioning)可知,同一主版本应当是向下兼容,因此同一主版本的高子版本应当能兼容低子版本。

例外:v0和v1似乎还是只能导入一个。有了v1就不能再用v0。
不过在语义化版本号中,v0代表试验的初期不稳定版本,有了v1就基本不会再有用v0的需求,问题不大。

代码示例:

go.mod

1
2
3
4
5
require (
github.com/abc/hello v1.0.0
github.com/abc/hello/v2 v2.1.3
github.com/abc/hello/v3 v3.2.1
)

在同一项目的不同的代码文件中使用同一库的不同主版本:

代码文件1.go

1
import "github.com/abc/hello"

代码文件2.go

1
import "github.com/abc/hello/v2"

代码文件3.go

1
import "github.com/abc/hello/v3"

在同一项目的同一代码文件中使用同一库的不同主版本:
(这个需求有点奇葩,不过也能实现,如果各主版本包名冲突,import时指定别名即可)
代码文件x.go

1
2
3
4
5
   import (
helloa "github.com/abc/hello"
hellob "github.com/abc/hello/v2"
helloc "github.com/abc/hello/v3"
)