Go语言的依赖管理之道

发表时间: 2024-05-13 17:52

Go语言的依赖管理

依赖的概念

依赖管理的三个阶段 GOPATH, GOVENDOR, go mod

GOPATH

默认在~/go(unix, linux), %USERPROFILE%\go(windows)

历史: Google将20亿行代码, 9百万个文件放在一个repo里

> # mkdir /tmp/gopathtest> # cd /tmp/gopathtest> # go env> # export GOPATH=/tmp/gopathtest> # mkdir src> # mkdir project1> # cd project1> # export GO111MODULE=off> # echo $GO111MODULE> # go env

export 只对当前窗口生效, src目录必须存在

https://github.com/uber-go/zap

> # go get -u go.uber.org/zap> # cd ..> # lsgo.uber.org project1
package mainimport ("go.uber.org/zap")func main() { //左括号必须和函数名同行log, _ := zap.NewProduction()log.Warn("warning test")}D:\project\src>go run main.go{"level":"warn","ts":1587045384.5491102,"caller":"src/main.go:10","msg":"warning test"}

查询GOPATH模式下包从哪里查找

package mainimport ("go.uber.org/zap""github.com/aaaa/bbb")func main() { //左括号必须和函数名同行bbb.N()log, _ := zap.NewProduction()log.Warn("warning test")}D:\project\src>go run main.gomain.go:5:2: cannot find package "github.com/aaaa/bbb" in any of:c:\go\src\github.com\aaaa\bbb (from $GOROOT)D:\project\src\github.com\aaaa\bbb (from $GOPATH)main.go:4:2: cannot find package "go.uber.org/zap" in any of:c:\go\src\go.uber.org\zap (from $GOROOT)D:\project\src\go.uber.org\zap (from $GOPATH)

从上面我们可以看到 包先从c:\go\src(from $GOROOT)查找, 然后从D:\project\src\(from $GOPATH) 查找

go env -w GOPROXY=https://goproxy.io,direct# Set environment variable allow bypassing the proxy for selected modulesgo env -w GOPRIVATE=*.corp.example.comgo env -w GO111MODULE=on

go env -w 命令是 1.13 版才支持的命令, 全局设置

GOVENDOR

每个项目有自己的vendor目录, 存放第三方库

大量第三方依赖管理工具: glide, dep, go dep, ...

目录结构:

D:\project\src\verdor\go.uber.org...D:\project\src\xiangmu1\verdor\go.uber.org...D:\project\src\xiangmu1\main.goD:\project\src\xiangmu2\verdor\go.uber.org...D:\project\src\xiangmu2\main.go

查询GOVENDOR模式下包从哪里查找

package mainimport ("go.uber.org/zap""github.com/aaaa/bbb")func main() { //左括号必须和函数名同行bbb.N()log, _ := zap.NewProduction()log.Warn("warning test")}
package mainimport ("go.uber.org/zap""github.com/aaaa/bbb")func main() { //左括号必须和函数名同行bbb.N()log, _ := zap.NewProduction()log.Warn("warning test")}main.go:5:2: cannot find package "github.com/aaaa/bbb" in any of:D:\project\src\xiangmu1\vendor\github.com\aaaa\bbb (vendor tree)D:\project\src\vendor\github.com\aaaa\bbbc:\go\src\github.com\aaaa\bbb (from $GOROOT)D:\project\src\github.com\aaaa\bbb (from $GOPATH)

从上面我们可以看到 包先从D:\project\src\xiangmu1\vendor(vendor tree)查找, 然后从D:\project\src\vendor\ 查找.....

注意: GOVENDOR模式不需要额外配置, 只是利用GOPATH模式的配置

go mod的使用

设置两个环境变量

GO111MODULE onGOPROXY https://goproxy.cnD:\project\src\xiangmu1>go mod init xiangmu1go: creating new go.mod: module xiangmu1
package mainimport ("go.uber.org/zap"//"github.com/aaaa/bbb")func main() { //左括号必须和函数名同行//bbb.N()log, _ := zap.NewProduction()log.Warn("warning test")}D:\project\src\xiangmu1>go get -u go.uber.org/zapD:\project\src\xiangmu1>go run main.gogo: finding go.uber.org/zap v1.14.1go: downloading go.uber.org/zap v1.14.1go: extracting go.uber.org/zap v1.14.1go: downloading go.uber.org/multierr v1.5.0go: downloading go.uber.org/atomic v1.6.0go: extracting go.uber.org/multierr v1.5.0go: extracting go.uber.org/atomic v1.6.0go: finding go.uber.org/atomic v1.6.0go: finding go.uber.org/multierr v1.5.0{"level":"warn","ts":1587175300.386373,"caller":"xiangmu1/main.go:11","msg":"warning test"}

查看go.mod文件

module xiangmu1go 1.13require go.uber.org/zap v1.14.1 // indirect

查看go.sum文件

github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo=go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=

由此可见, go mod 自动通过https://goproxy.cn 国内镜像下载包

存放地址: D:\project\pkg\mod\go.uber.org

下载其他版本的包

D:\project\src\xiangmu1>go get -u go.uber.org/zap@v1.11go: finding go.uber.org/zap v1.11.0go: downloading go.uber.org/zap v1.11.0go: extracting go.uber.org/zap v1.11.0

查看go.mod文件

module xiangmu1go 1.13require (github.com/pkg/errors v0.8.1 // indirectgithub.com/stretchr/testify v1.4.0 // indirectgo.uber.org/multierr v1.5.0 // indirectgo.uber.org/zap v1.11.0 // indirect)

修改go.mod文件 go.uber.org/zap v1.11.0 修改为 go.uber.org/zap v1.12.0

module xiangmu1go 1.13require (github.com/pkg/errors v0.8.1 // indirectgithub.com/stretchr/testify v1.4.0 // indirectgo.uber.org/multierr v1.5.0 // indirectgo.uber.org/zap v1.12.0 // indirect)

清理无用的依赖

go mod tidy

我们发现go.uber.org/zap v1.11.0已经被清理掉了

下载不指定版本

D:\project\src\xiangmu1>go get -u go.uber.org/zap

go.mod文件

module xiangmu1go 1.13require (github.com/pkg/errors v0.9.1 // indirectgo.uber.org/zap v1.14.1)main.gopackage mainimport ("github.com/gin-gonic/gin""go.uber.org/zap")func main() { //左括号必须和函数名同行//bbb.N()log, _ := zap.NewProduction()log.Warn("warning test")gin.N()}D:\project\src\xiangmu1>go run main.gogo: finding github.com/gin-gonic/gin v1.6.2go: downloading github.com/gin-gonic/gin v1.6.2go: extracting github.com/gin-gonic/gin v1.6.2go: downloading github.com/mattn/go-isatty v0.0.12go: downloading github.com/golang/protobuf v1.3.3go: downloading github.com/gin-contrib/sse v0.1.0go: downloading gopkg.in/yaml.v2 v2.2.8go: downloading github.com/ugorji/go v1.1.7go: downloading github.com/go-playground/validator/v10 v10.2.0go: extracting github.com/gin-contrib/sse v0.1.0go: extracting github.com/mattn/go-isatty v0.0.12go: extracting github.com/golang/protobuf v1.3.3go: extracting gopkg.in/yaml.v2 v2.2.8go: extracting github.com/ugorji/go v1.1.7go: downloading github.com/ugorji/go/codec v1.1.7go: extracting github.com/go-playground/validator/v10 v10.2.0go: downloading github.com/leodido/go-urn v1.2.0go: downloading github.com/go-playground/universal-translator v0.17.0go: extracting github.com/ugorji/go/codec v1.1.7go: extracting github.com/go-playground/universal-translator v0.17.0go: downloading github.com/go-playground/locales v0.13.0go: extracting github.com/leodido/go-urn v1.2.0go: extracting github.com/go-playground/locales v0.13.0go: finding github.com/gin-contrib/sse v0.1.0go: finding github.com/go-playground/validator/v10 v10.2.0go: finding github.com/go-playground/universal-translator v0.17.0go: finding github.com/go-playground/locales v0.13.0go: finding github.com/leodido/go-urn v1.2.0go: finding github.com/golang/protobuf v1.3.3go: finding github.com/ugorji/go/codec v1.1.7go: finding gopkg.in/yaml.v2 v2.2.8go: finding github.com/mattn/go-isatty v0.0.12# command-line-arguments.\main.go:12:2: undefined: gin.N

我们发现 运行 go run main.go 自动帮助我们下载github.com/gin-gonic/gin包

go.mod文件

module xiangmu1go 1.13require (github.com/gin-gonic/gin v1.6.2 // indirectgithub.com/pkg/errors v0.9.1 // indirectgo.uber.org/zap v1.14.1)

拉取所有的依赖库, 项目迁移时要用到(在 执行初始化命令 "go mod init 项目包名称"后执行)

go build ./...D:\project\src\xiangmu1>go build ./...

go mod 总结

由go命令统一的管理, 用户不必关心目录结构

初始化: go mod init

增加依赖: go get

更新依赖:

go get [@v...]

go mod tidy

项目迁移

go mod init

go build ./...