go-module场景总结
- 1.引用自己的fork
- 2.修改fork后的项目自立门户
- 3.报错-module declares its path as X,but was required as Y
- 4.找到依赖项目了,但是找不到package
- 5.两阶段构建优化
- 6.有可能被间接引用过的包
- 7.依赖兼容性问题
- 8.pgpme
- 9.module name是不是可以不用仓库名前缀
- 10. 引用kubernetes源码
1.引用自己的fork
replace 原始=>fork 分支/版本
例:
replace github.com/evanw/esbuild => github.com/matthewmueller/esbuild master
2.修改fork后的项目自立门户
- go module名称改成自己的
- replace:
原始 => ./
例:fork了kubekey后,github.com/kubesphere/kubekey => ./
3.报错-module declares its path as X,but was required as Y
报错详情如下:
gopkg.in/urfave/cli.v2: gopkg.in/urfave/cli.v2@v2.3.0: parsing go.mod:
module declares its path as: github.com/urfave/cli/v2
but was required as: gopkg.in/urfave/cli.v2
通过go mod edit replace将required改为declared即可
go mod edit -replace=${required}${version}=${declared}${version}
4.找到依赖项目了,但是找不到package
通常是因为依赖引用的版本用了latest,而现在的latest和当时的latest在代码结构上已经变了
解决方案:根据项目的时间,倒推出大致的版本,用go mod edit replace将latest版本指定为过去的某个版本
go mod edit -replace=google.golang.org/grpc@latest=google.golang.org/grpc@v1.17.0
# go会自动在go.mod里将latest展开成当前的最高版本,go.mod里会看到如下的结果:
replace google.golang.org/grpc v1.50.1 => google.golang.org/grpc v1.17.0
5.两阶段构建优化
ENV GOPROXY https://goproxy.cn
# go mod tidy会打破缓存,download不会
RUN go mod download
6.有可能被间接引用过的包
基于k8s二次开发时,用到的一些公共的库,有较大概率在引用k8s.io相关的库时已经被间接引用过了。此时最好不要go get latest,应当先去go mod里查一下是否有引用及其版本,如果可用的话,用那个版本即可,避免引起依赖冲突
7.依赖兼容性问题
基于k8s的二次开发中,编译报错:
# k8s.io/component-base/logs/json
../../../../go/pkg/mod/k8s.io/component-base@v0.21.14/logs/json/json.go:47:21: cannot use &zapLogger{} (value of type *zapLogger) as type logr.Logger in variable declaration
../../../../go/pkg/mod/k8s.io/component-base@v0.21.14/logs/json/json.go:129:9: cannot use &zapLogger{…} (value of type *zapLogger) as type logr.Logger in return statement
../../../../go/pkg/mod/k8s.io/component-base@v0.21.14/logs/json/json.go:138:9: cannot use l (variable of type *zapLogger) as type logr.Logger in return statement
../../../../go/pkg/mod/k8s.io/component-base@v0.21.14/logs/json/json.go:144:9: cannot use l (variable of type *zapLogger) as type logr.Logger in return statement
../../../../go/pkg/mod/k8s.io/component-base@v0.21.14/logs/json/json.go:167:9: cannot use &zapLogger{…} (value of type *zapLogger) as type logr.Logger in return statement
# k8s.io/klog/v2
../../../../go/pkg/mod/k8s.io/klog/v2@v2.9.0/klog.go:705:13: invalid operation: logr != nil (mismatched types logr.Logger and untyped nil)
../../../../go/pkg/mod/k8s.io/klog/v2@v2.9.0/klog.go:724:13: invalid operation: logr != nil (mismatched types logr.Logger and untyped nil)
../../../../go/pkg/mod/k8s.io/klog/v2@v2.9.0/klog.go:742:13: invalid operation: logr != nil (mismatched types logr.Logger and untyped nil)
../../../../go/pkg/mod/k8s.io/klog/v2@v2.9.0/klog.go:763:13: invalid operation: logr != nil (mismatched types logr.Logger and untyped nil)
搜索相关资料可以找到这个issue:controller-runtime is broken by github.com/go-logr/logr v1.0.0 · Issue #1607 · kubernetes-sigs/controller-runtime
里面提到了和报错相关的一个依赖的不兼容变更。
查看项目的go mod发现间接依赖的正是发生了不兼容修改后的github.com/go-logr/logr@v1.2.0,用replace将其改为老版本即可。
8.pgpme
go build cmd/kk/main.go
# pkg-config --cflags -- gpgme
Package gpgme was not found in the pkg-config search path.
Perhaps you should add the directory containing `gpgme.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gpgme' found
pkg-config: exit status 1
brew install gpgme
9.module name是不是可以不用仓库名前缀
永远用module xxxxxx
不用module github.com/y/xxxxxx
A:当项目是终端项目,不会暴露给别人引用时,可以这么用
10. 引用kubernetes源码
kubernetes仓库中的部分模块有意设计为不允许外部直接引用,在引用这些模块时go mod会报错,关键词为
at revision v0.0.0: unknown revision
解决方法是用脚本做一些workaround实现这类源码的下载和导入
详情参考本博客调度器开发的内容,其中有专门章节提到:基于kubernetes调度框架的自定义调度器实现 - Lwabish Index (wubw.fun)
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。