go mod镜像加速
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
清除缓存
- 清除所有的包缓存
go clean --modcache
- 清除特定版本的包缓存(暂时没发现)
目录结构
目录为go/pkg/mod
├── cache
├── dubbo.apache.org
├── github.com
├── gitlab.dian.org.cn
├── git.sublive.app
├── go.etcd.io
├── golang.org
├── google.golang.org
├── gopkg.in
├── gorm.io
├── go.uber.org
└── vimagination.zapto.org
cache记录压缩包和校验文件等内容
不同的网站拥有不同的文件夹存放
包与路径
- import的是包的路径,不是包名,会根据import的值去寻找这个路径下的包
- import之后会去路径下找包,找到文件中第一行声明的package才是真正的包名
- 路径下的包名可以和目录不一样(最好一样),但是同一个路径只能有一个包名
私有仓库包获取
- go env -w GOPRIVATE="*.gitlab.cn" 设置为私有仓库
- go env -w GONOPROXY="*.gitlab.cn" 设置不走代理
- 编辑
~/.netrc
文件(这个文件是纯文本文件不能使用任何的环境变量)
machine git.gitlab.cn login chenxuan password 123456789
- 第三步也可以更改为编辑
~/.gitconfig
文件
[url "ssh://git@github.com/"]
insteadOf = https://github.com/
git config --global http.sslverify false
解除git ssl验证
某个pkg最新版本
- 更改go.mod中的包版本为v0.0.0
gitlab不支持ssh拉取多级私有包
问题原因
- go get分两个过程,可以使用
go get -v
查看记录- 获取链接的源信息,即meta data,此时使用的是https协议
- 下载代码,此时使用的是ssh(当然这里也可以更改为http)
- 超过2的sub目录在 未认证的情况下因为可能是仓库的信息(也可能是sub目录,一级不可能是仓库),这里涉及仓库信息,因此https没带这token禁止获取
- 使得go get命令无法获取超过1 的仓库的meta data,无法clone
解决办法
netrc
- 方法参考Go包管理 > 私有仓库包获取
- 核心是走https,meta请求就携带pwd,可以获取
- 优点:简单方便
- 缺点:cicd根本用不了,会信息泄漏
replace
- 核心参考参考
require (
private.gitlab.instance/project/team/somename v1.0.0
)
replace (
private.gitlab.instance/project/team/somename => private.gitlab.instance/project/team/somename.git v1.0.0
)
- 添加.git后缀,这个办法也可以改进为直接包名带着.git
- 优点:能解决问题,而且没有信息泄漏问题,简单方便
- 缺点:丑陋,莫名其妙带上.git
相关讨论连接
- https://github.com/golang/go/issues/34094#issuecomment-556898897
- https://gitlab.com/gitlab-org/gitlab/-/issues/36354
go多级包管理
go mod init github.com/{帐号}/{仓库名字}/{子包的名字}
,目录demo
.
├── README.md
├── a
│ ├── a.go
│ └── go.mod
└── b
├── b.go
└── go.mod
- 需要注意的是,这时候的tag规则是
{子包的相对路径}/v1.0.0
git tag
a/v1.0.0
b/v1.0.0
b/v1.0.1
- import的时候是tag需要注意
import (
github.com/robberphex/go-test-multi-module/a v1.0.0
)
- 参考:https://learnku.com/articles/58947 和 https://tonybai.com/2023/05/10/a-guide-of-managing-multiple-go-modules-in-mono-repo/
引用特定分支
- 直接使用
go get
命令 类似go get github.com/golang/go@master
- 直接在go.mod文件中添加,格式: git地址 v0.0.0-时间戳- commint id 例如: github.com/golang/go v0.0.0-20221013081251-69aaa89ae530
依赖地狱
- 项目引用了 A包和B包, A和B都引用了C包, 但是A用的是v1.0,B用的是v2.0, C包的v2.0不兼容 v1.0 , 导致崩溃无法编译
- go mod的解决办法是通过package路径加上version使得两个包依赖的完全是不同的的包, 使得同一个程序可以存在两个相同名字版本不同的包(本质依赖了包本身是隔离的,不会引起冲突的问题)
- 第一个代价就是构建出来的app的二进制文件size变大了,因为二进制文件中包含了多个版本的P3的代码;第二个代价,可能也算不上代价,更多是要注意的是不同版本的module之间的类型、变量、标识符不能混用
- 需要注意的是: 这种的多版本共存的情况只存在于, 两个package version的 major 版本发生了不同, 如果是同一个major, 那么会使用最大的版本号(可能出现不兼容问题)
[!tip] 参考 为什么有了Go module后“依赖地狱”问题依然存在 | Tony Bai