Go——依賴管理

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
圖片.png

在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

  1. 升級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"
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。