go mod 排雷记
Golang升级到1.13.x之后,使用"go mod"来改造原有的Project遇到了很多坑,今天来总结一下go mod的用法。
1. GO111MODULE
"go mod"即go module。
要使用go module
,首先要设置GO111MODULE=on
,这没什么可说的。
一般在golang 1.13.x 安装时配置好环境变量即可,Ubuntu下设置见上篇: Golang 升级1.13+ 后的配置
2. 已有项目(go mod改造)
2.1 使用远程包
假设你已经有了一个go 项目, 比如在 $GOPATH/github.com/hyperledger/go-exampl
e下, 你可以使用go mod init github.com/
在这个文件夹下创建一个空的hyperledger/go-exampl
ego.mod。
然后你可以通过 go get ./...
让它查找依赖,并记录在go.mod
文件中(你还可以指定 -tags
,这样可以把tags的依赖都查找到)。
通过go mod tidy
也可以用来为go.mod
增加丢失的依赖,删除不需要的依赖,但是我不确定它怎么处理tags
。执行上面的命令会把go.mod
的latest
版本换成实际的最新的版本,并且会生成一个go.sum
记录每个依赖库的版本和哈希值。
gomod中根据第三方的指定版本进行编译,如我要拿v1.4.9的fabric导入而非最新版本:
module xxx go 1.15 replace github.com/hyperledger/fabric => github.com/hyperledger/fabric v1.4.9
2.2 使用本地包
比如原有项目使用本地路径的我修改过的fabric-sdk-go的包,下载load远程包的话会build出错,可以用replace来转用本地包。
编辑项目下go.mod文件,加上一行用replace来替换包路径:
- 官方远程包: github.com/hyperledger/fabric-sdk-go v1.0.0-beta1
- 替换本地包:/home/bear/go/src/github.com/hyperledger/fabric-sdk-go
module go-example go 1.13 require ( github.com/bitly/go-simplejson v0.5.0 github.com/ghodss/yaml v1.0.0 github.com/hyperledger/fabric-sdk-go v1.0.0-beta1 github.com/pkg/errors v0.9.1 ) replace github.com/hyperledger/fabric-sdk-go => /home/bear/go/src/github.com/hyperledger/fabric-sdk-go
3. 新的项目
你可以在GOPATH
之外创建新的项目。
go mod init packagename
可以创建一个空的go.mod
,然后你可以在其中增加require github.com/
依赖,或者像上面一样让go自动发现和维护。hyperledger/go-exampl
e latest
go mod download
可以下载所需要的依赖,但是依赖并不是下载到$GOPATH
中,而是$GOPATH/pkg/mod
中,多个项目可以共享缓存的module。
4. go mod命令
- download download modules to local cache (下载依赖的module到本地cache))
- edit edit go.mod from tools or scripts (编辑go.mod文件)
- graph print module requirement graph (打印模块依赖图))
- init initialize new module in current directory (再当前文件夹下初始化一个新的module, 创建go.mod文件))
- tidy add missing and remove unused modules (增加丢失的module,去掉未用的module)
- vendor make vendored copy of dependencies (将依赖复制到vendor下)
- verify verify dependencies have expected content (校验依赖)
- why explain why packages or modules are needed (解释为什么需要依赖)
5. FQ
在国内访问golang.org/x
的各个包都需要FQ,你可以在go.mod
中使用replace
替换成github上对应的库。
replace ( golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac => github.com/golang/crypto v0.0.0-20180820150726-614d502a4dac golang.org/x/net v0.0.0-20180821023952-922f4815f713 => github.com/golang/net v0.0.0-20180826012351-8a410e7b638d golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0 )
依赖库中的replace
对你的主go.mod
不起作用,比如github.com/
的hyperledger/go-exampl
ego.mod
已经增加了replace
,但是你的go.mod
虽然require
了go-exampl
e的库,但是没有设置replace
的话, go get
还是会访问golang.org/x
。
所以如果想编译那个项目,就在哪个项目中增加replace
。
6. 版本格式
以下版本格式都是合法的:
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 gopkg.in/vmihailenco/msgpack.v2 v2.9.1 gopkg.in/yaml.v2 <=v2.2.1 github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e latest
7. go get 升级
- 运行
go get -u
将会升级到最新的次要版本或者修订版本(x.y.z, z是修订版本号, y是次要版本号) - 运行
go get -u=patch
将会升级到最新的修订版本 - 运行
go get package@version
将会升级到指定的版本号version
8. go mod vendor
go mod vendor
会复制modules下载到vendor中, 貌似只会下载你代码中引用的库,而不是go.mod中定义全部的module。
9. go module, vendor 和 Travis CI
https://arslan.io/2018/08/26/using-go-modules-with-vendor-support-on-travis-ci/
阅读文档资料:
https://github.com/golang/go/wiki/Modules
https://roberto.selbach.ca/intro-to-go-modules/