vendor
在Go1.5 release的版本的發布vendor目錄被添加到除了GOPATH和GOROOT之外的依賴目錄查找的解決方法。
查找依賴包路徑的解決
當前包下的vendor目錄
先上級的目錄查找,直到找到scr的vendor目錄
在GOPATH下面查找依賴包
在GOROOT目錄下查找
dep
dep安裝方式的安裝方式是:執行 curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
$ curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 5140 100 5140 0 0 3346 0 0:00:01 0:00:01 --:--:-- 3346
ARCH = amd64
OS = linux
Will install into /home/baxiang/go/bin
Fetching https://github.com/golang/dep/releases/latest..
Release Tag = v0.5.0
Fetching https://github.com/golang/dep/releases/tag/v0.5.0..
Fetching https://github.com/golang/dep/releases/download/v0.5.0/dep-linux-amd64..
Setting executable permissions.
Moving executable to /home/baxiang/go/bin/dep
MacOS 使用 Homebrew安裝
$ brew install dep
$ brew upgrade dep
Linux Apt安裝
sudo apt install go-dep
通過go get 按照
go get -u github.com/golang/dep/cmd/dep
dep常用命令
$ dep
Dep is a tool for managing dependencies for Go projects
Usage: "dep [command]"
Commands:
init Set up a new Go project, or migrate an existing one
status Report the status of the project's dependencies
ensure Ensure a dependency is safely vendored in the project
version Show the dep version information
check Check if imports, Gopkg.toml, and Gopkg.lock are in sync
Examples:
dep init set up a new project
dep ensure install the project's dependencies
dep ensure -update update the locked versions of all dependencies
dep ensure -add github.com/pkg/errors add a dependency to the project
Use "dep help [command]" for more information about a command.
初始化
文件目錄結構
$ tree
.
├── Gopkg.lock
├── Gopkg.toml
└── vendor
1 directory, 2 files
在Gopkg.toml編輯
[[constraint]]
name = "github.com/pkg/errors"
source = "github.com/pkg/errors"
version = "0.8.1"
[[constraint]]
name = "github.com/gorilla/websocket"
source = "github.com/gorilla/websocket"
version = "1.4.0"
[[constraint]]
name = "github.com/skip2/go-qrcode"
source = "github.com/skip2/go-qrcode"
branch = "master"
go mod
- 升級golang 版本到 1.12 Go下載
設置環境變量
export GO111MODULE=on
bogon:~ baxiang$ source ~/.bash_profile
bogon:~ baxiang$ echo $GO111MODULE
auto
go mod 命令
go mod help
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 init [module]:初始化.mod 包管理文件到當前工程。
go mod vendor:vendor版本的解決方案,將依賴復制到vendor下面。
go mod tidy:移除未用的模塊,以及添加缺失的模塊。
go mod verify:驗證所有模塊是否正確。
初始化模塊
go mod init
go: modules disabled inside GOPATH/src by GO111MODULE=auto; see 'go help modules'
在當前目錄下,命令行運行 go mod init + 模塊名稱 初始化模塊
export GO111MODULE=on
$ go mod init server
go: creating new go.mod: module mServer
go: copying requirements from Gopkg.lock
運行完后,會在當前項目目錄下生成一個go.mod 文件,這是一個關鍵文件,之后的包的管理都是通過這個文件管理。
除了go.mod之外,go命令還維護一個名為go.sum的文件,其中包含特定模塊版本內容的預期加密哈希,go.sum 文件不需要手工維護。
go.mod工作機制
main.go文件:
package main
import (
"github.com/gin-contrib/pprof"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
pprof.Register(router)
router.Run(":8000")
}
按照過去的做法,要運行main.go需要執行go get
命令 下載gin包到 $GOPATH/src。
go get -u github.com/gin-gonic/gin
go 會自動查找代碼中的包,下載依賴包,并且把具體的依賴關系和版本寫入到go.mod和go.sum文件中。
查看go.mod,它會變成這樣:
module baxiang.cn/GoNote
go 1.12
replace (
golang.org/x/text => github.com/golang/text v0.3.0
golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0
)
require (
github.com/gin-contrib/pprof v1.2.0
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 // indirect
github.com/gin-gonic/gin v1.3.0
github.com/golang/protobuf v1.3.1 // indirect
github.com/json-iterator/go v1.1.6 // indirect
github.com/mattn/go-isatty v0.0.7 // indirect
github.com/ugorji/go v1.1.4 // indirect
)
require關鍵子是引用,后面是包,最后v1.3.0 是引用的版本號
使用Go mod依賴的第三方包被默認下載到$GOPATH/pkg/mod
路徑下。
go mod使用vendor目錄
如果你不喜歡 go mod 的緩存方式,你可以使用vendor命令回到 godep 或 govendor 使用的 vendor 目錄進行包管理的方式。
go mod vendor
當然這個命令并不能讓你從godep之類的工具遷移到 go modules,它只是單純地把 go.sum 中的所有依賴下載到 vendor 目錄里,如果你用它遷移 godep 你會發現 vendor 目錄里的包會和 godep 指定的產生相當大的差異,所以請務必不要這樣做。
使用 go build -mod=vendor 來構建項目,因為在 go modules 模式下 go build 是屏蔽 vendor 機制的,所以需要特定參數重新開啟 vendor 機制:
go build -mod=vendor
構建成功。當發布時也只需要和使用 godep 一樣將 vendor 目錄帶上即可
依賴包的版本管理
:gin-gonic baxiang$ tree -L 1
.
├── gin@v0.0.0-20190328061400-ce20f107f5dc
├── gin@v1.1.4
└── gin@v1.3.0
3 directories, 0 files
在上一個問題里,可以看到最終下載在$GOPATH/pkg/mod
下的github.com/gin-gonic
的gin包@ vx.x.x,代表著不同的version,$GOPATH/pkg/mod
里可以保存相同包的不同版本。
版本是在go.mod中指定的。
如果,在go.mod中沒有指定,go命令會自動下載代碼中的依賴的最新版本,本例就是自動下載最新的版本。
如果,在go.mod用require語句指定包和版本 ,go命令會根據指定的路徑和版本下載包,
指定版本時可以用latest
,這樣它會自動下載指定包的最新版本;如果包的作者還沒有標記版本,默認為 v0.0.0
go get 命令
新版 go get
可以在末尾加 @
符號,用來指定版本。
它要求倉庫必須用 v1.2.0
格式打 tag,像 v1.2
少個零都不行的,必須是語義化的、帶 v
前綴的版本號。其中latest
匹配最新的 tag。
go get github.com/gorilla/mux # 匹配最新的一個 tag
go get github.com/gorilla/mux@latest # 和上面一樣
go get github.com/gorilla/mux@v1.6.2 # 匹配 v1.6.2
go get github.com/gorilla/mux@e3702bed2 # 匹配 v1.6.2
go get github.com/gorilla/mux@c856192 # 匹配 c85619274f5d
go get github.com/gorilla/mux@master # 匹配 master 分支
replace
golang.org/x/… 等包在中國大陸區域無法下載
依賴包地址變更
在go.mod文件里用 replace 替換包地址
replace (
golang.org/x/text => github.com/golang/text latest
golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0
)
go mod會用 github.com/golang/text 替代golang.org/x/text,原理就是下載github.com/golang/text 的最新版本到 $GOPATH/pkg/mod/golang.org/x/text
下。
goproxy.io
goproxy.io Github 可以給go modules 設置全局代理,下載golang/x的包文件 也就就不需要設置replace
Linux 和mac OS
export GOPROXY=https://goproxy.io
powershell (windows)
$env:GOPROXY = "https://goproxy.io"