golang go.mod
2023-12-23 00:23 youxin 阅读(150) 评论(0) 编辑 收藏 举报go mod 指定并加载版本号
4.1. 方法一 go mod指定替换版本
在项目的go.mod中用replace指定包版本号,比如:
replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
4.2. 方法二 go mod指定大小版本
配置依赖库及其指定版本
import导入时指定依赖大版本,项目中直接指定版本githubAddr/version,大版本号添加v1、v2等等,如后面不加/v等,则默认为v0或v1版本的大版本。该方法可以解决go get的时候报错invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2。该大版本主要依赖git项目Release版本。
import (
badger "github.com/dgraph-io/badger/v3"
cache "github.com/eko/gocache/v2/cache" //依赖子项采用如下方式
metrics "github.com/eko/gocache/v2/metrics"
store "github.com/eko/gocache/v2/store"
)
同时也可以通过以下指定依赖版本,但仅限小版本号。
go mod edit -require=github.com/dgraph-io/badger/v3@v3.2011.1
配置下载相关依赖库及其版本
下载指定小版本v3.2011.1: go get -u -x github.com/dgraph-io/badger/v3@v3.2011.1
可以在本地GOPATH中查看到具体路径/root/go/pkg/mod/github.com/dgraph-![](https://turbock79.cn/wp-content/uploads/2020/05/微信截图_20210701103527.png)io/badger/v3@v3.2011.1,go mod会自动下载对应tag的指定节点;
然后再go mod tidy下载所以相关依赖,并删除不需要模块;
4.3. 方法三 go mod指定版本HASH值获取
通过浏览器获取想要获取版本的对应hash值,但是该方法对于版本更新不是很友好,需要不断调整。获取hash如下图
使用gobgp版本号
#添加指定版本号的hash获取该版本
go get github.com/osrg/gobgp@915bfc2
#查看go.mod版本,获取
require (
...
github.com/osrg/gobgp v0.0.0-20210402043138-915bfc2d8189 // indirect
参考文章:https://github.com/osrg/gobgp/issues/2274
————————————————
版权声明:本文为CSDN博主「Turbock」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/turbock/article/details/106251473
总览
Go 专家编程 go mod incompatible
在前面的章节中,我们介绍了Go module的版本选择机制,其中介绍了一个Module的版本号需要遵循v<major>.<minor>.<patch>的格式,此外,如果major版本号大于1时,其版本号还需要体现在Module名字中。
比如Module github.com/RainbowMango/m,如果其版本号增长到v2.x.x时,其Module名字也需要相应的改变为: github.com/RainbowMango/m/v2。即,如果major版本号大于1时,需要在Module名字中体现版本。
那么如果Module的major版本号虽然变成了v2.x.x,但Module名字仍保持原样会怎么样呢? 其他项目是否还可以引用呢?其他项目引用时有没有风险呢?这就是今天要讨论的内容。
go mod 语义版本规范
在Go module时代,module版本号要遵循语义化版本规范,即版本号格式为v<major>.<minor>.<patch>,如v1.2.3。当有不兼容的改变时,需要增加major版本号,如v2.1.0。
Go module规定,如果major版本号大于1,则major版本号需要显式地标记在module名字中,如module github.com/my/mod/v2。这样做的好处是Go module 会把module github.com/my/mod/v2 和 module github.com/my/mod视做两个module,他们甚至可以被同时引用。
imcompatible 的作用是什么?
虽说有了 go mod 语义版本规范,但有人不遵循呀
# 以Module `github.com/RainbowMango/m` 为例,假如其当前版本为`v3.6.0`
require (
github.com/RainbowMango/m v3.6.0+incompatible
)
# 而按照go mod 语义版本规范定义,应该新建个 mod ,命名为 github.com/RainbowMango/m/v3
不遵循规范,开发者就无法清除了解【兼容性的变动情况】,可能会给项目的依赖带来风险
1. 能否引用不兼容的包
我们还是以Module github.com/RainbowMango/m 为例,假如其当前版本为v3.6.0,因为其Module名字未遵循Golang所推荐的风格,即Module名中附带版本信息,我们称这个Module为不规范的Module。
不规范的Module还是可以引用的,但跟引用规范的Module略有差别。
如果我们在项目A中引用了该module,使用命令go mod tidy,go 命令会自动查找Module m的最新版本,即v3.6.0。 由于Module为不规范的Module,为了加以区分,go 命令会在go.mod中增加+incompatible 标识。
require (
github.com/RainbowMango/m v3.6.0+incompatible
)
除了增加+incompatible(不兼容)标识外,在其使用上没有区别。
2. 如何处理incompatible
go.mod文件中出现+incompatible,说明你引用了一个不规范的Module,正常情况下,只能说明这个Module版本未遵循版本化语义规范。但引用这个规范的Module还是有些困扰,可能还会有一定的风险。
比如,我们拿某开源Module github.com/blang/semver为例,编写本文时,该Module最新版本为v3.6.0,但其go.mod中记录的Module却是:
module github.com/blang/semver
1
Module github.com/blang/semver 在另一个著名的开源软件Kubernetes(github.com/kubernetes/kubernetes)中被引用,那么Kubernetes的go.mod文件则会标记这个Module为+incompatible:
require (
...
github.com/blang/semver v3.5.0+incompatible
...
)
站在Kubernetes的角度,此处的困扰在于,如果将来 github.com/blang/semver发布了新版本v4.0.0,但不幸的是Module名字仍然为github.com/blang/semver。那么,升级这个Module的版本将会变得困难。因为v3.6.0到v4.0.0跨越了大版本,按照语义化版本规范来解释说明发生了不兼容的改变,即然不兼容,项目维护者有必须对升级持谨慎态度,甚至放弃升级。
站在github.com/blang/semver的角度,如果迟迟不能将自身变得"规范",那么其他项目有可能放弃本Module,转而使用其他更规范的Module来替代,开源项目如果没有使用者,也就走到了尽头。
————————————————
版权声明:本文为CSDN博主「oceanweave」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_24433609/article/details/127325233
# module名称
module mit-go
# go 版本
go 1.15
# require 用来定义依赖包的版本
# 后面的// indirect表示间接依赖,通常如果有间接依赖说明import写的有问题或者依赖的包存在问题
require github.com/Januslll/mit-go v0.0.0-20200827115747-2ab09a53eea2// indirect
这个时候就表示已经拉取到依赖了,依赖的格式通常为版本号+时间戳+hash,例如我这里就是v0.0.0-20200827115747-2ab09a53eea2
。
其中版本号是v0.0.0,这就表示没有版本的控制,官方建议通过git tag
加上版本号,如下所示:
git tag v1.0.0
git push --tags
加上后就会变成v1.0.0版本。
间戳和hash分别表示commit提交的时间戳和commit记录的hash值取前12位,输入git log
可查看,如下所示:
commit 2ab09a53eea24dcbb01307b77bb5ed08080ababc (HEAD -> master, tag: v1.0.0, origin/master, origin/HEAD)
Author: Janus <274123369@qq.com>
Date: Thu Aug 27 19:57:47 2020 +0800
可以通过修改版本号、时间戳、hash来实现依赖版本的管理。同样,go mod还提供了依赖添加和删除的语句:
# 添加依赖
go mod edit -require=github.com/Januslll/mit-go
# 移除依赖
go mod edit -droprequire=github.com/Januslll/mit-go
另外还会看到一个文件go.sum
文件,里面记录了每个依赖包的hash值,防止下载的依赖包有被篡改的可能性,如果篡改了则拒绝构建,对里面的实现感兴趣的可以移步go.dev/blog/module… 。
使用私有仓库
公司内部往往会使用公司私有仓库,这个时候只配置了GOPROXY
是无法获取得到依赖的。
在go 1.13版本后,提供了GOPRIVATE
环境变量来配置私有仓库。
# 在~/.bashrc下或~/.zshrc下添加环境配置,例如gitlab.com/xxx是公司私有仓库
# 该配置可以用逗号分开配置多个仓库
export GOPRIVATE=gitlab.com/xxx
#或者采用命令进行环境配置
$ go env -w GOPRIVATE=gitlab.com/xxx
配置了之后,还需要配置私有仓库的访问权限设置,我这里采用ssh
进行配置。由于我需要将个人用户和工作用户隔离开故需要配置不同的ssh,这里记录下如何配置。
# 分别生成ssh key
ssh-keygen -t rsa -C "your_email@example.com" -f ~/.ssh/id_rsa_gitlab
ssh-keygen -t rsa -C "your_email@example.com" -f ~/.ssh/id_rsa_github
# 添加私钥
ssh-add ~/.ssh/id_rsa_gitlab
ssh-add ~/.ssh/id_rsa_github
# ssh配置
vim ~/.ssh/config
# ~/.ssh/config配置内容
# Host:别名
# Hostname:git服务器名字 一般都是github.com 或者公司自己的gitlab
# User:用户名
# IdentityFile:ssh key的文件
# 个人ssh
Host github
Hostname github.com
User Janus
IdentityFile ~/.ssh/id_rsa_github
# 工作ssh
Host gitlab
Hostname gitlab.com
User Janus
IdentityFile ~/.ssh/id_rsa_gitlab
#测试配置,其中temp为上面的HOST,如果Host为github,则为git@github
ssh -T git@temp
# 分别配置用户信息
cd my_project
git config --local user.name "yourName"
git config --local user.email "your_email@example.com"
cd work_project
git config --local user.name "yourName"
git config --local user.email "your_email@example.com"
跟着上面的步骤即可配置完成,有个坑点是如果你原本是https的需要更改为ssh,例如:
git config --global url."git@github.com:Januslll/mit-go.git".insteadOf "https://github.com/Januslll/mit-go.git"
最后把ssh添加到账户的github.com/gitlab.com页面的SSH keys上面去即可。
综上,Go的整个配置环境完成,如有疑问欢迎交流。