1. 簡介
GO Modules
也稱作go mod
是golang 官方最新的幾個golang 版本中推出的包
管理方式或者稱作模塊
支持golang 中
modules
(模塊)是什麼意思呢?一個模塊是一系列 Go 代碼包 的集合,它們保存在同一個文件樹中。文件樹的根目錄中包含了一個
go.mod
文件。go.mod
文件定義了一個模塊的 module path,這就是模塊根目錄的導入路徑。go.mod
文件還定義了模塊的 dependency requirements(依賴項要求),即爲了編譯本模塊,需要用到哪些其它的模塊。每一項依賴項要求都包含了依賴項的 module path,還要指定它的語義版本號。在最新的golang版本
golang 1.13
中是默認的包管理方式,那麼在golang的後期版本中Go Modules
基本可以認爲是官方推薦的依賴管理工具
GO modules 是解決啥問題的?
Golang在早期的版本中(golang 1.11版本之前) 包管理一直沒有一個統一方案,表現出問題如:
- 所有的依賴包都必須在
GOPATH
同一個庫只能保存一個版本的代碼,那麼不同的項目要依賴同一個包的不同版本那就很尷尬了.- 工作目錄必須在
GOPATH/src
目錄下使用了
Go Modules
之後就可在GOPATh/src
之外創建目錄和管理包了我們大概回顧一下
golang 1.5
版本之前所有的依賴包都必須放在GOPATH
下面,沒有版本管理golang 1.5
版本之後推出vendor
機制golang 1.9
版本出現了包管理工具dep
golang1.11
版本推出modules
機制對包進行管理,在之後的版本中modules
逐步得到了加強, 在golang1.13
中成爲默認的包管理方式並且是默認開啓的
2. 基礎命令
go mod
的命令其實不多我們打開命令行工具
$ go help mod Go mod provides access to operations on modules. Note that support for modules is built into all the go commands, not just 'go mod'. For example, day-to-day adding, removing, upgrading, and downgrading of dependencies should be done using 'go get'. See 'go help modules' for an overview of module functionality. Usage: go mod <command> [arguments] The commands are: download download modules to local cache edit edit go.mod from tools or scripts graph print module requirement graph init initialize new module in current directory tidy add missing and remove unused modules vendor make vendored copy of dependencies verify verify dependencies have expected content why explain why packages or modules are needed Use "go help mod <command>" for more information about a command.
顯示的
go mod
實際命令只有如下幾個
命令 意思 go mod download 下載依賴的Module到本地緩存 go mod edit 編輯go.mod文件 go mod graph 打印模塊依賴圖 go mod init 初始化當前目錄中的新模塊,創建go.mod文件 go mod tidy 增加缺失的Module,刪除無效的Module go mod vendor 將依賴複製到vendor下 go mod verify 校驗依賴 go mod why 解釋package或者modules爲啥被依賴
3. 基本使用
3.1 go mod init
我們在非
GOPATH/src
目錄下執行
go mod init
後面是模塊名稱 ,名稱自定義即可$ go mod init github.com/captain/modDemo go: creating new go.mod: module github.com/captain/modDemo
這樣在項目(模塊)目錄下多出了一個文件
go.mod
文件我們看看
go.mod
中的內容module github.com/captain/modDemo go 1.12
我們下載一個依賴包試試
// 執行 如下命令 go get -u github.com/gin-gonic/gin
初次執行下依賴包的命令後會多出一個文件
go.sum
go.sum
是由 go命令行工具維護的,其中記錄了每個依賴庫的版本和哈希值,其作用是確保項目依賴的模塊不會發生變化執行完之後,我們再看看
go.mod
的內容module github.com/apiDemo go 1.12 require ( github.com/gin-gonic/gin v1.5.0 // indirect github.com/go-playground/universal-translator v0.17.0 // indirect github.com/json-iterator/go v1.1.8 // indirect github.com/leodido/go-urn v1.2.0 // indirect github.com/mattn/go-isatty v0.0.10 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect github.com/stretchr/objx v0.2.0 // indirect golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1 // indirect golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 // indirect golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 // indirect golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d // indirect golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/go-playground/validator.v9 v9.30.2 // indirect gopkg.in/yaml.v2 v2.2.7 // indirect )
go.mod
文件簡介:
module
用來定義包名和我們初始化的包名是一致的
require
定義依賴的包及其對應的版本
indirect
標識間接引用
3.1 下載指定版本的依賴庫
go list -m all
列出當前模塊和它的依賴庫$ go list -m all github.com/captain/modDemo github.com/davecgh/go-spew v1.1.1 github.com/gin-contrib/sse v0.1.0 github.com/gin-gonic/gin v1.5.0 github.com/go-playground/locales v0.13.0 github.com/go-playground/universal-translator v0.17.0 github.com/golang/protobuf v1.3.2 github.com/google/gofuzz v1.0.0 github.com/json-iterator/go v1.1.8 github.com/leodido/go-urn v1.2.0 github.com/mattn/go-isatty v0.0.10 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd github.com/modern-go/reflect2 v1.0.1 github.com/pmezard/go-difflib v1.0.0 github.com/stretchr/objx v0.2.0 github.com/stretchr/testify v1.4.0 github.com/ugorji/go v1.1.7 github.com/ugorji/go/codec v1.1.7 golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 golang.org/x/net v0.0.0-20191207000613-e7e4b65ae663 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab golang.org/x/text v0.3.2 golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 gopkg.in/go-playground/assert.v1 v1.2.1 gopkg.in/go-playground/validator.v9 v9.30.2 gopkg.in/yaml.v2 v2.2.7
go list -m -versions 庫名地址
列出一個模塊能用的版本$ go list -m -versions github.com/gin-gonic/gin github.com/gin-gonic/gin v1.1.1 v1.1.2 v1.1.3 v1.1.4 v1.3.0 v1.4.0 v1.5.0
go mod tidy
刪除無效的modules$ go mod tidy $ go list -m all github.com/captain/modDemo
我們拿比較常見的 一個庫xrom
做示例 下載指定的版本
可見
xorm
可用的版本很多
$ go list -m -versions github.com/go-xorm/xorm
github.com/go-xorm/xorm v0.2.1 v0.2.2 v0.2.3 v0.3.1 v0.3.2 v0.4.1 v0.4.2 v0.4.3 v0.4.4 v0.4.5 v0.5.0 v0.5.1 v0.5.2 v0.5.3 v0.5.4 v0.5.6 v0.5.7 v0.5.8 v0.6.2 v0.6.3 v0.6.4 v0.6.5 v0.6.6 v0.7.0 v0.7.1 v0.7.2 v0.7.3 v0.7.4 v0.7.5 v0.7.6 v0.7.7 v0.7.8 v0.7.9
go mod
想下載指定的版本 通常我們有三種做法
go get 包路徑@v版本號
go get 包路徑@分支
分支是指在github上提交的分支
go get 包路徑@git提交的哈希
我們看到目前
xorm
最新版本是v0.7.9
但是我想下載比較舊一點的版本v0.7.5
$ go get github.com/go-xorm/[email protected] go: finding github.com/go-xorm/xorm v0.7.5 go: finding github.com/jackc/pgx v3.3.0+incompatible go: finding xorm.io/core v0.7.0 go: finding github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 go: finding github.com/cockroachdb/apd v1.1.0 go: finding xorm.io/builder v0.3.5 go: finding github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 go: finding github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 go: finding github.com/ziutek/mymysql v1.5.4 go: finding github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a go: finding golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468 go: finding google.golang.org/appengine v1.6.0 go: finding golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed go: downloading github.com/go-xorm/xorm v0.7.5 go: extracting github.com/go-xorm/xorm v0.7.5 go: downloading xorm.io/builder v0.3.5 go: downloading xorm.io/core v0.7.0 go: extracting xorm.io/builder v0.3.5 go: extracting xorm.io/core v0.7.0 $ cat go.mod module github.com/captain/modDemo go 1.12 require github.com/go-xorm/xorm v0.7.5 // indirect
3.2 更新依賴庫
通常下載一個包沒有明確指定版本,那麼下載的包就是當前的最新版本
我們還是拿
xorm
包作爲示例$ go get github.com/go-xorm/xorm go: finding github.com/jackc/pgx v3.6.0+incompatible go: finding xorm.io/builder v0.3.6 go: finding xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb go: downloading github.com/go-xorm/xorm v0.7.9 go: extracting github.com/go-xorm/xorm v0.7.9 go: downloading xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb go: downloading xorm.io/builder v0.3.6 go: extracting xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb go: extracting xorm.io/builder v0.3.6 $ cat go.mod module github.com/captain/modDemo go 1.12 require ( github.com/go-xorm/xorm v0.7.9 // indirect github.com/golang/protobuf v1.3.1 // indirect github.com/kr/pretty v0.1.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed // indirect golang.org/x/text v0.3.2 // indirect golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468 // indirect )
我們看到了結果現在
xorm
更新到了當前最新版本v0.7.9
那我可不可以更新到一個指定的版本呢?其實做法是一樣的就是指定一個版本號就可以了
$ go get github.com/go-xorm/[email protected] go: finding github.com/go-xorm/xorm v0.7.7 go: finding xorm.io/builder v0.3.6-0.20190906062455-b937eb46ecfb go: downloading github.com/go-xorm/xorm v0.7.7 go: extracting github.com/go-xorm/xorm v0.7.7 $ cat go.mod module github.com/captain/modDemo go 1.12 require ( github.com/go-xorm/xorm v0.7.7 // indirect github.com/golang/protobuf v1.3.1 // indirect github.com/kr/pretty v0.1.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed // indirect golang.org/x/text v0.3.2 // indirect golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468 // indirect xorm.io/builder v0.3.6 // indirect xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb // indirect )
3.3 go get簡介
go get
命令可以遠程拉取更新代碼包和依賴包,並自動完成編譯和安裝
go get
命令實際是分成了兩步操作 1. 下載源碼包 2.執行go insert
簡單的理解是 :
go get
=git clone
+go insert
這是一個常見的遠程包的格式 : github.com/go-xorm/xorm
github.com
是網站域名
go-xorm
我們可以理解問作者或者機構名稱
xorm
就是項目名稱
go get
命令的具體詳情可以查看它的幫助命令
對命令附帶的可用參數有很詳細的介紹
$ go help get
usage: go get [-d] [-m] [-u] [-v] [-insecure] [build flags] [packages]
Get resolves and adds dependencies to the current development module
and then builds and installs them.
The first step is to resolve which dependencies to add.
我們只看幾個很常見的
-d
只下載,而不安裝
-u
強制使用網絡去更新包和它的依賴包
-v
顯示執行的命令
-t
同時也下載需要爲運行測試所需要的包
-fix
讓命令程序在下載代碼包後先執行修正動作,而後再進行編譯和安裝。
-x
打印安裝的具體過程
-insecure
允許命令程序使用非安全的scheme(如HTTP)去下載指定的代碼包
-f
僅在使用-u
標記時纔有效。該標記會讓命令程序忽略掉對已下載代碼包的導入路徑的檢查