目录
1. 简介
2.能否引起不兼容的包
3.如何处理incompatible
Go module的版本选择机制,其中介绍了一个Module的版本号需要遵循<code>v<major>.<minor>.<patch></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来替代,开源项目如果没有使用者,也就走到了尽头。