天天看点

Go版本管理--处理不兼容

目录

​​1. 简介​​

​​2.能否引起不兼容的包​​

​​3.如何处理incompatible​​

Go module的版本选择机制,其中介绍了一个Module的版本号需要遵循​<code>​v&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;​</code>​的格式,此外,如果major版本号大于1时,其版本号还需要体现在Module名字中。

比如​<code>​Module github.com/RainbowMango/m​</code>​,如果其版本号增长到​<code>​v2.x.x​</code>​时,其Module名字也需要相应的改变为:

​<code>​github.com/RainbowMango/m/v2​</code>​。即,如果major版本号大于1时,需要在Module名字中体现版本。

那么如果Module的major版本号虽然变成了v2.x.x,但Module名字仍保持原样会怎么样呢? 其他项目是否还可以引用呢?其他项目引用时有没有风险呢?这就是今天要讨论的内容。

以​<code>​以Module github.com/RainbowMango/m​</code>​ 为例,假如其当前版本为​<code>​v3.6.0​</code>​,因为其Module名字未遵循Golang所推荐的风格,即​<code>​Module​</code>​名中附带版本信息,我们称这个Module为不规范的Module。

不规范的Module还是可以引用的,但跟引用规范的Module略有差别。

如果我们在项目A中引用了该module,使用命令​<code>​go mod tidy​</code>​,go 命令会自动查找Module m的最新版本,即v3.6.0。

由于Module为不规范的Module,为了加以区分,go 命令会在​<code>​go.mod​</code>​中增加​<code>​+incompatible​</code>​ 表示

除了增加​<code>​+incompatible(不兼容)​</code>​标识外,在其使用上没有区别。

go.mod文件中出现​<code>​+incompatible​</code>​,说明你引用了一个不规范的Module,正常情况下,只能说明这个Module版本未遵循版本化语义规范。但引用这个规范的Module还是有些困扰,可能还会有一定的风险。

比如,我们拿某开源​<code>​Module​</code>​ ​<code>​github.com/blang/semver​</code>​为例,编写本文时,该Module最新版本为v3.6.0,但其​<code>​go.mod​</code>​中记录的Module却是:

Module ​<code>​github.com/blang/semver​</code>​ 在另一个著名的开源软件​<code>​Kubernetes(github.com/kubernetes/kubernetes)​</code>​中被引用,那么​<code>​Kubernetes​</code>​的​<code>​go.mod​</code>​文件则会标记这个​<code>​Module为+incompatible​</code>​:

站在​<code>​Kubernetes​</code>​的角度,此处的困扰在于,如果将来 ​<code>​github.com/blang/semver​</code>​发布了新版本​<code>​v4.0.0​</code>​,但不幸的是Module名字仍然为​<code>​github.com/blang/semver​</code>​。那么,升级这个Module的版本将会变得困难。因为​<code>​v3.6.0​</code>​到​<code>​v4.0.0​</code>​跨越了大版本,按照语义化版本规范来解释说明发生了不兼容的改变,即然不兼容,项目维护者有必须对升级持谨慎态度,甚至放弃升级。

站在​<code>​github.com/blang/semver​</code>​的角度,如果迟迟不能将自身变得”规范”,那么其他项目有可能放弃本Module,转而使用其他更规范的Module来替代,开源项目如果没有使用者,也就走到了尽头。