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/