- 取得連結
- 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.mod- module hello
- go 1.12
- build
$ go build
go.mod 多出一行 require
多出 go.sum,內為依賴版本的 Hash- module hello
- go 1.12
- require rsc.io/quote v1.5.2
- 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/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,並標注為 indirect- module 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
hello_test.go
- package hello
- import (
- "rsc.io/quote"
- quoteV3 "rsc.io/quote/v3"
- )
- func Hello() string {
- return quote.Hello()
- }
- func Proverb() string {
- return quoteV3.Concurrency()
- }
執行測試
- 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)
- }
- }
可發現 rsc.io/quote 有兩個版本
- $ 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
go.mod
- $ go list -m rsc.io/q...
- rsc.io/quote v1.5.2
- rsc.io/quote/v3 v3.1.0
go.sum
- module hello
- go 1.12
- require (
- rsc.io/quote v1.5.2
- rsc.io/quote/v3 v3.1.0
- )
順帶一提,如下,加了版本,仍是使用原來的 module 名,除非有重新指定
- 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=
- 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
test/go.mod
- package hello
- func Hello() string {
- println("hello")
- return "Hello, world."
- }
test2/hello.go
- module ttt //不影響運行
- go 1.12
test2/go.mod
- package main
- import "test/hello" //可以是錯誤的路徑,只要 replace 是對的
- func main() {
- hello.Hello()
- }
執行測試,需在 go.mod 的資料夾中
- module main
- go 1.12
- require test/hello v0.0.0 // 虛擬版號
- // 取代為真正的路徑,可為絕對或相對路徑,但注意為 go.mod 所在的資料夾
- replace test/hello => ../test
- $ 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
留言
張貼留言