- 取得連結
- X
- 以電子郵件傳送
- 其他應用程式
程式語言:Go
官方 wiki 文件
功能:套件管理,V1.11 之後才支援,建議搭配 VCS (例:github)
gvm + go mod
关于Go Module的争吵
Go 語言 1.11 版本推出 go module
go modules详解
跳出Go module的泥潭
語意化版本 2.0.0
- 工具:
- go mod
官方 wiki 文件
功能:套件管理,V1.11 之後才支援,建議搭配 VCS (例:github)
環境變數設定
使用 modules,build|test|install 需在 go.mod 的目錄下,不然會出錯
go.mod & go.sum 必須要加入版控,以確保在不同版本都能成功的 build
go.mod & go.sum 必須要加入版控,以確保在不同版本都能成功的 build
- GO111MODULE
- unset or auto
- Inside GOPATH
- 預設跟 1.10 行為一樣 (忽略 modules)
- Outside GOPATH
- 當存在 go.mod,則為 modules 行為
- on
- 強制為 modules 行為,即使 inside GOPATH
- off
- 強制為 1.10 的行為,即使擁有 go.mod
簡易步驟
- 移至 Project 目錄
$ cd <project path outside $GOPATH/src> # e.g., cd ~/projects/hello
若 Project 位於 GOPATH 中,需設定以下環境變數
$ export GO111MODULE=on # manually active module mode
- 建立 go.mod
$ go mod init github.com/my/repo
module 名字可任意,通常與 VCS 相關 - build|test|install 後,go.mod 將自動加入依賴,且 pkg 下載到 GOPATH/pkg/mod 內
$ go build|test|install ./...
- 測試確認
$ go test ./...
- 測試 all direct and indirect dependencies,防止不相容
$ go test ./...
簡單範例
- 測試 code,hello.go
package main import ( "fmt" "rsc.io/quote" ) func main() { fmt.Println("Hello World") quote.Hello() }
- 初始化 mod
$ go mod init hello
得到 go.modmodule hello go 1.12
- build
$ go build
go.mod 多出一行 requiremodule hello go 1.12 require rsc.io/quote v1.5.2
多出 go.sum,內為依賴版本的 Hashgolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y= rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
- 列出目前的依賴
$ go list -m all
hello golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c rsc.io/quote v1.5.2 rsc.io/sampler v1.3.0
- 更新 text 為 tag 版本
$ go get golang.org/x/text
go.mod 多出一行 require,並標注為 indirectmodule hello go 1.12 require ( golang.org/x/text v0.3.2 // indirect rsc.io/quote v1.5.2 )
升级更新
- 升級到最新的版本
$ go get
- 升級到最新的次要版本或者修訂版本 (x.y.z,z 是修訂版本號, y 是次要版本號)
$ go get -u
- 升級到最新的修訂版本
$ go get -u=patch
- 升級到指定的版本號 version
$ go get package@version
版本號命名規則 semver
以下命名皆合法,詳細說明可參考連結
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
指定不同版本的 module 範例
hello.go
package hello import ( "rsc.io/quote" quoteV3 "rsc.io/quote/v3" ) func Hello() string { return quote.Hello() } func Proverb() string { return quoteV3.Concurrency() }hello_test.go
package hello import "testing" func TestProverb(t *testing.T) { want := "Concurrency is not parallelism." if got := Proverb(); got != want { t.Errorf("Proverb() = %q, want %q", got, want) } }執行測試
$ go test go: finding rsc.io/quote/v3 v3.1.0 go: downloading rsc.io/quote/v3 v3.1.0 go: extracting rsc.io/quote/v3 v3.1.0 PASS ok hello 1.391s可發現 rsc.io/quote 有兩個版本
$ go list -m rsc.io/q... rsc.io/quote v1.5.2 rsc.io/quote/v3 v3.1.0go.mod
module hello go 1.12 require ( rsc.io/quote v1.5.2 rsc.io/quote/v3 v3.1.0 )go.sum
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y= rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=順帶一提,如下,加了版本,仍是使用原來的 module 名,除非有重新指定
package hello import ( "rsc.io/quote/v3" ) func Proverb() string { return quote.Concurrency() }
本地依賴範例
Folder └── test └── hello.go └── go.mod └── test2 └── hello.go └── go.modtest/hello.go
package hello func Hello() string { println("hello") return "Hello, world." }test/go.mod
module ttt //不影響運行 go 1.12test2/hello.go
package main import "test/hello" //可以是錯誤的路徑,只要 replace 是對的 func main() { hello.Hello() }test2/go.mod
module main go 1.12 require test/hello v0.0.0 // 虛擬版號 // 取代為真正的路徑,可為絕對或相對路徑,但注意為 go.mod 所在的資料夾 replace test/hello => ../test執行測試,需在 go.mod 的資料夾中
$ cd test2 $ go run hello.go hello
命令
- go mod download
- 下載依賴的 module 到本地 cache,go get|build|test|install 有同樣效果
- go mod edit
- 編輯 go.mod 文件,需搭配 flag,可查看說明
go help mod edit
- go mod graph
- 印出 module 依賴圖
- go mod init
- 在當前文件夾下初始化一個新的 module, 建立 go.mod 文件
- go mod tidy
- 增加丟失的 module,去掉未用的 module
- go mod vendor
- 將依賴複製到 vendor
- go mod verify
- 校驗依賴
- go mod why
- 解釋為什麼需要依賴
- go list -m
- 列出所有的依賴
參考
浅析 golang modulegvm + go mod
关于Go Module的争吵
Go 語言 1.11 版本推出 go module
go modules详解
跳出Go module的泥潭
語意化版本 2.0.0
留言
張貼留言