首页 > 其他分享 >go.mod版本管理

go.mod版本管理

时间:2024-10-10 21:24:56浏览次数:1  
标签:依赖 版本号 tag 版本 go mod

 

 

写在前面

       现在大部分 go 项目使用 go.mod 做版本控制,虽然能做到依赖的多版本共存,但是也会碰到一些不太好理解的地方,这里对此进行一些记录,方便查阅。

go module 版本格式

       go.mod使用的版本号协议是 semver (Semantic Versioning),定义的版本号格式为:

vMAJOR.MINOR.PATCH
MAJOR 主版本号,如果有大的版本更新,导致 API 和之前版本不兼容。我们遇到的就是这个问题。
MINOR 次版本号,当你做了向下兼容的新 feature。
PATCH 修订版本号,当你做了向下兼容的修复 bug fix。
v 所有版本号都是 v 开头。

在 go.mod 文件中见到的所有的依赖包均是上述格式。如果依赖的第三方包中打的 tag 不符合上面的标准或者根本没有打 tag,那么 go.mod 中会自动生成满足上述格式的伪版本号,这个时候可以查看伪版本号中的最后一个数字,最后一个数字是仓库中的 commitId,commitId 是正确的就是没问题的。

标准样式

       类似下面格式,表明在 sarama 的库中打了 v1.26.4 的 tag。注意,必须是打 v1.26.4 这样的 tag,如果打的 tag 是 1.26.4、v1.26.4.2 等样式均不符合 go.mod 的标准,go.mod 中均会生成伪版本号,所以尽量用标准形式打 tag。

github.com/Shopify/sarama v1.26.4

伪版本号

        tag 不符合标准或者没有 tag 就会生成伪版本号,类似下面这样

github.com/faceair/sarama v1.27.3-0.20201026102015-6f053e317d37

       生成伪版本号的时候主要就看最后一个数字,最后一个数字代表提交到仓库的 commitId,可以根据这个 commitId 确定当前在使用那个版本的代码。
       伪版本号具体的含义如下:v0.0.0-yyyymmddhhmmss-abcdefabcdef
       yyyymmddhhmmss表示提交到仓库的时间,abcdefabcdef就表示 commitId。如果打的 tag 为 v1.27.2.3(多用了一个小数点),生产的伪版本号中就会变成示例中的样子。

间接依赖

       在使用 Go module 过程中,随着引入的依赖增多,也许你会发现go.mod文件中部分依赖包后面会出现一个// indirect的标识。这个标识总是出现在require指令中,其中//与代码的行注释一样表示注释的开始,indirect表示间接的依赖。

       比如开源软件 Kubernetes(v1.17.0版本)的 go.mod 文件中就有数十个依赖包被标记为indirect:

require (
    github.com/Rican7/retry v0.1.0 // indirect
    github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7 // indirect
    github.com/boltdb/bolt v1.3.1 // indirect
    github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b // indirect
    github.com/codegangsta/negroni v1.0.0 // indirect
    ...
)

       在执行命令go mod tidy时,Go module 会自动整理go.mod 文件,如果有必要会在部分依赖包的后面增加// indirect注释。一般而言,被添加注释的包肯定是间接依赖的包,而没有添加// indirect注释的包则是直接依赖的包,即明确的出现在某个import语句中。

       然而,这里需要着重强调的是:并不是所有的间接依赖都会出现在 go.mod文件中。

       间接依赖出现在go.mod文件的情况,可能符合下面所列场景的一种或多种:

  • 直接依赖未启用 Go module
  • 直接依赖go.mod 文件中缺失部分依赖

不兼容标识+incompatible

       +incompatible 标识项目中引入了一个不兼容的包。产生的原因是项目中引用的第三方依赖的版本已经升级到 v2 甚至更高,但是第三方包的 module name 没有显式加上 v2 标识。正确做法应该是让第三方包的 module name 显式加上 v2 标识,然后重新打一个 v2 版本的 tag,然后在自己的项目中使用新的 tag。

       产生了不兼容标识对第三方依赖包会有所影响,因为他们本身没有按照规范打 tag,这种标识会让使用方知道他们正在使用的包发生了不兼容的变更,不利于第三方包的推广。

replace 语句

       go.mod 中的 replace 语句只会对当前项目产生影响,不会对其他引用该项目的代码产生影响。
       项目中使用 replace 主要有以下几个用途:

  1. 替换成镜像包,某些包无法直接下载,用 replace 替换成镜像包后就可以下载成功,使用时仍然使用原来的 replace 前的 module name
  2. 想要隐藏项目中使用的包的版本,require 中将包的版本定义成v0.0.0,然后在 replace 中替换成其他版本。主要用于某些项目不想让其他项目引用的情况,k8s 的库便是如此
  3. 将某些包替换成其他的包。可以这样做,但是不如直接使用 replace 之后的包。
  4. 使用本地的其他项目,本地其他项目必须用 replace,可以用相对路径和绝对路径引用到另一个项目的根路径中即可。

       上面说的四种用途其实都是在说一件事,使用 replace 之后项目中实际使用的代码其实是 replace 之后的包的代码。

用到的一些 go 命令

go mod tidy

       比较常用的一个命令,该命令会自动整理依赖,可以添加依赖,删除不需要的依赖,同时还会对 go.sum 文件进行修改。手动修改go.mod 中某个包的版本,然后执行 go mod tidy 相当于执行 go get 命令

go get

       用于下载或更新包,下载时不指定包的版本默认会下载最新包,需要指定版本时包名和版本号之间用『@』符号相连(中间没有空格)。指定版本时可以使用仓库中打的 tag、commitId 或者 branchName,如果 tag 不符合标准,在下载时要先使用不标准的 tag,下载完成会后自动变成伪版本号。

go mod download

       在 go.mod 手动修改版本号,然后可以执行 go mod download 下载,该命令不会对包进行整理,go.sum 也不会修改,执行完后应该再执行一下 go mod tidy

go clean -modcache

       如果有时候下载包一直不成功,有可能是缓存中的包冲突导致,可以使用该命令将缓存删除,然后执行 go mod tidy 重新下载所有的包。

总结

       还是熟能生巧,要多踩些坑,才能更快解决碰到的问题。

标签:依赖,版本号,tag,版本,go,mod
From: https://www.cnblogs.com/rebrobot/p/18457169

相关文章

  • Go 疑难杂症汇总
      GoModules终极入门https://eddycjy.com/posts/go/go-moduels/2020-02-28-go-modules/             https://www.cnblogs.com/xingzheanan/p/15700302.html1. revisionv0.0.0:unknownrevisionv0.0.0goget-ugithub.com/uudashr/gopkgs/......
  • 20AB-day3 Good Subsegments
    20AB-day3GoodSubsegments题意给你一个长度为\(n\)的序列\(a\),问有多少个子区间,满足\(\sum_{i=l}^r2^{a_i}=2^x\),其中\(x\)为非负整数。原题解第一个想法:若\(2^{a_l}+2^{a_{l+1}}+\cdots+2^{a_r}=2^x\),则\(x\le\max(a_l,a_{l+1},\cdots,a_r)+\logn\)。第二......
  • springboot多项目融合为springcloud微服务项目(1)之版本选择、依赖冲突
    一、版本选择、依赖冲突1、需要注意springboot、cloud、cloudalibaba之间的版本,避免出现版本冲突。可以去springcloudalibabagithub中挑选版本,官方给出了合适的版本说明,点击既可跳转:https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明我选择的版本是: <!-......
  • 哔咔漫画下载最新版本2024技巧
    电脑制作漫画的流程通常包括以下几个步骤:构思与策划明确漫画的主题、风格以及目标受众。哔咔漫画制定故事大纲,包括主要情节、人物设定等。剧本编写哔咔漫画编写详细的脚本,包括对话、哔咔漫画动作描述、场景说明等。脚本应该清晰地指示每个镜头的内容,以便后续的绘图工作。......
  • Open X-Embodiment: Robotic Learning Datasets and RT-X Models
    OpenX-Embodiment:RoboticLearningDatasetsandRT-XModels启发:在不同数据集上训练大规模、高容量模型以处理下游应用方面取得显著成功。是否能将所有数据整合在高容量机器人操作模型上使其有效适应新的机器人、任务、环境?贡献:提供了标准化数据格式和模型的数据集,收......
  • web端ant-design-vue Modal.info组件自定义icon和title使用小节
     web端ant-design-vueModal.info组件自定义icon和title整理小节,最近在项目中用到了自定义icon和title的功能,经过测试发现,如果自定义icontitle会自动换行,尝试直接修改样式和穿透方式都没有效果,最后采取了一个巧妙的方式,将icon和title放在一个自定义组件内,完美解决!代码如下......
  • 开源项目更新|WPF/Uno Platform/WinUI 3三个版本的《英雄联盟客户端》
    ​哈喽大家好!我们是中韩MicrosoftMVP夫妇Vicky&James^^很高兴能加入博客园和大家分享我们的技术!自2008年以来,我们一直深耕于WPF技术,积累了丰富的经验。这些年来,随着Xamarin、MAUI、Uno-Platform、AvaloniaUI和OpenSilver等跨平台技术的不断发展,我们也将在WPF中积累的技能成功......
  • 2024激活Typora,最新版本的1.9.5可用
    目前最新版本 1.9.5也是可以实现激活的注:免修改注册表、不用修改时间,更不需要破解补丁01、下载&安装Typora从官网下载最新版本的Typora,并安装02、激活Typora找到Typora安装目录,依次找到这个文件resources\page-dist\static\js\LicenseIndex.**********.********.chunk.js......
  • 28. 找出字符串中第一个匹配项的下标 Golang实现
    题目描述:给你两个字符串haystack和needle,请你在haystack字符串中找出needle字符串的第一个匹配项的下标(下标从0开始)。如果needle不是haystack的一部分,则返回-1。示例1:输入:haystack="sadbutsad",needle="sad"输出:0解释:"sad"在下标0和6处匹配。......
  • pg大版本升级
    pg大版本升级环境9.6.24升级到14.13同一台机器本地升级步骤新版本需要初始化数据库initdb。创建测试数据:sysbench--db-driver=pgsql--pgsql-host=127.0.0.1--pgsql-port=5432--pgsql-user=postgres--pgsql-db=testdb--table_size=10000000--tables=1--threa......