一、了解Go包管理的动机
我们知道etcd使用Go实现的,前段时间准备看下etcd源码,结果用go get下载安装etcd源码问题层出不穷,表面的原因是etcd依赖的Go模块有循环依赖,深层次原因还是Go包管理处在混乱及快速演进的过程中。
所以,想阅读调试etcd源码,必须跨过对Go包管理不熟悉这道坎。
不得不先说一句,Go包管理工具真是混乱至极,尤其是用了下Node.js的包管理工具npm(最近项目用到了Node.js, 简单用了用),没有对比就伤害。
二、Go包管理工具的混沌
2017年,刚开始用Go开发项目的时候,使用的还是vendor的包模式,当时以为Go就是这样,也没有觉得有什么问题,随着最近的了解,才直到Go的包管理从没有,到社区版的工具,到官方自带的工具,一直在剧烈的变化。
1、monorepo 模式
2、社区维护准官方包管理工具 dep
vendor 包模式
3、go module
注:每种工具详情待补充
三、Go官方包管理工具Go Module
该工具是语言自带的,命令为go mod。
查看手册go help mod
salmonl@B-3BD9Q05P-2155 amap-aos-mozhu-srp % 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.
1、要解决的问题
管理依赖的包
跟踪包的依赖关系
模块版本化
2、用法
2.1、配置环境变量
go version go version go1.15.8 darwin/amd64 go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct
2.2、在$GOPATH之外新建一个项目文件hello
mkdir -p /Users/luckbo/go_test/hello
2.3、新建一个测试文件
cd /Users/luckbo/go_test/hello touch hello.go
内容如下
package main import "fmt" import "rsc.io/quote" func main() { fmt.Println(quote.Go()) }
2.4、创建空的go.mod
go mod init hello
会在当前目录下生成两个文件go.mod(依赖包信息)和go.sum(包的md5信息)
cat go.mod module hello go 1.15
go.sum是
2.5、go mod tidy [-v]
2.6、go mod vendor [-v]
2.7、go build的时候就会下载依赖包rsc.io/quote
go build hello.go
同时在go.mod只增加包信息
cat go.mod
module hello go 1.15 require rsc.io/quote v1.5.2 // indirect
实际包存储位置为$GOPATH/pkg/mod
cd /Users/luckbo/go/pkg/mod ls cache golang.org rsc.io
2.8、执行
./hello Don't communicate by sharing memory, share memory by communicating.
注:
使用go module管理包,新建的项目源代码就不用强制放在$GOPATH/src下了;
如果不使用 Go Modules, go get 将会从模块代码的 master分支拉取,而若使用 Go Modules 则你可以利用 Git Tag 手动选择一个特定版本的模块代码。
四、常见问题
1、提示无法导入包could not import
以包wodeploy/cmd为例
“wodeploy/cmd” imported but not used compiler
could not import wodeploy/cmd (no required module provides package “wodeploy/cmd”)
可能原因:
使用了包中不可见的方法, 或者方法名写错了,导致包没有被使用,VS保存的时候就会自动去掉导入包
cmd.dockerBuild()
五、参考
1、Go包管理
Go 包管理的前世今生
2、go module的资料
官方wiki:https://github.com/golang/go/wiki/Modules#quick-start
官方博客:https://blog.golang.org/using-go-modules
优质博文:Playing with Go module proxies(中文版: Go 语言的 Modules 系统介绍)
视频教程:https://www.youtube.com/watch?v=cfcT_3ad-_0
完整案例:https://liulantao.com/golang-hello-world.html
知乎:开始使用 Go Module
鸟窝:跳出Go module的泥潭
Go modules简介
六、TODO
1、补充,参考https://segmentfault.com/a/1190000022868683