目录
Go包管理工具:前言
Golang一直存在一个被人诟病的问题是缺少一个官方的包依赖管理工具。从我个人的角度上来看存在两个问题:
- GOPATH特性对于多工程的情况下,支持不算友好。
- GOPATH无法对依赖包进行有效的版本管理,没有任何地方能够表明依赖包的具体版本号,无法简单清晰获取到有效的依赖包版本信息等。
GOPATH
GOPATH
1. 在 1.8 版本前必须设置这个环境变量
2. 1.8 版本后(含 1.8)如果没有设置使⽤用默认值
- 在 Unix 上默认为 $HOME/go , 在 Windows 上默认为 %USERPROFILE%/go
- 在 Mac 上 GOPATH 可以通过修改 ~/.bash_profile 来设置
$GOPATH/src
src/
github.com/golang/example/
.git/ # Git repository metadata
outyet/
main.go # command source
main_test.go # test source
stringutil/
reverse.go # package source
reverse_test.go # test source
相比其他语言,这个限制有些无法理解。其实,这和 Go 的一设计理念紧密相关:
包管理应该是去中心化的
go get
github.com/user/repo
vendor、dep
go get
dep 的定位是实验、探索如何管理版本,并不会直接集成到 Go 工具链,Go 核心团队会吸取 dep 使用经验与社区反馈,开发下一代包管理工具 modules,并于 2019/09/03 发布的 1.13 正式支持,并随之发布 Module Mirror, Index, Checksum,用于解决软件分发、中间人攻击等问题。下图截取自 Go 官方博客
Go modules
Go modules机制在go 1.11中是experiment feature,按照Go的惯例,在新的experiment feature首次加入时,都会有一个特性开关,go modules也不例外,GO111MODULE这个临时的环境变量就是go module特性的experiment开关。
GO111MODULE有三个值:auto、on和off,默认值为auto。
GO111MODULE的值会直接影响Go compiler的“依赖管理”模式的选择(是GOPATH mode还是module-aware mode),我们详细来看一下:
当GO111MODULE的值为off时,go modules experiment feature关闭,go compiler显然会始终使用GOPATH mode,即无论要构建的源码目录是否在GOPATH路径下,go compiler都会在传统的GOPATH和vendor目录(仅支持在gopath目录下的package)下搜索目标程序依赖的go package;
当GO111MODULE的值为on时(export GO111MODULE=on),go modules experiment feature始终开启,与off相反,go compiler会始终使用module-aware mode,即无论要构建的源码目录是否在GOPATH路径下,go compiler都不会在传统的GOPATH和vendor目录下搜索目标程序依赖的go package,而是在go mod命令的缓存目录($GOPATH/pkg/mod)下搜索对应版本的依赖package;
当GO111MODULE的值为auto时(不显式设置即为auto),也就是我们在上面的例子中所展现的那样:使用GOPATH mode还是module-aware mode,取决于要构建的源码目录所在位置以及是否包含go.mod文件。
如果要构建的源码目录不在以GOPATH/src为根的目录体系下,且包含go.mod文件(两个条件缺一不可),那么使用module-aware mode;
否则使用传统的GOPATH mode。
Module 文件
go build && go mod tidy
项目根目录下会生成两个文件(需要加入到 git 中):
go.modpackage.jsongo.sumpackage-lock.json
Module 是多个 package 的集合,版本管理的基本单元,使用 go.mod 文件记录依赖的 module。
go.mod 位于项目的根目录,支持 4 条命令:module、require、replace、exclude。示例:
module github.com/my/repo
require (
github.com/some/dependency v1.2.3
github.com/another/dependency/v4 v4.0.0
)
v(major).(minor).(patch)
go mod命令
go mod
go mod 有以下命令:
命令 | 说明 |
---|---|
download | download modules to local cache(下载依赖包) |
edit | edit go.mod from tools or scripts(编辑go.mod) |
graph | print module requirement graph (打印模块依赖图) |
init | initialize new module in current directory(在当前目录初始化mod) |
tidy | add missing and remove unused modules(拉取缺少的模块,移除不用的模块) |
vendor | make vendored copy of dependencies(将依赖复制到vendor下) |
verify | verify dependencies have expected content (验证依赖是否正确) |
why | explain why packages or modules are needed(解释为什么需要依赖) |
Go modules使用步骤:
#方式1:临时设置
注意
# Windows环境用set
# linux环境用export
#########Windows#########
# 开启
set GO111MODULE=on
# 1.13 之后才支持多个地址,之前版本只支持一个
set GOPROXY=https://goproxy.cn,https://mirrors.aliyun.com/goproxy,direct
# 1.13 开始支持,配置私有 module,不去校验 checksum
set GOPRIVATE=*.corp.example.com,rsc.io/private
#########Linux#########
# 开启
export GO111MODULE=on
# 1.13 之后才支持多个地址,之前版本只支持一个
export GOPROXY=https://goproxy.cn,https://mirrors.aliyun.com/goproxy,direct
# 1.13 开始支持,配置私有 module,不去校验 checksum
export GOPRIVATE=*.corp.example.com,rsc.io/private
#方式2:全局设置
# 设置全局开启 go mod Go1.16版本默认为on,可跳过这一步
go env -w GO111MODULE=on
# 设置全局代理地址
go env -w GOPROXY=https://goproxy.cn,https://mirrors.aliyun.com/goproxy,direct
go module的文件下载后位置:
存储下载的依赖包,具体位置在$GOPATH/pkg/mod
在 Go 1.8 版本之前,GOPATH 环境变量默认是空的。从 Go 1.8 版本开始,Go 开发包在安装完成后,将 GOPATH 赋予了一个默认的目录,参见下表。
平 台 | GOPATH 默认值 | 举 例 |
---|---|---|
Windows 平台 | %USERPROFILE%/go | C:\Users\用户名\go |
Unix 平台 | $HOME/go | /home/用户名/go |
代理地址
https://goproxy.cn //七牛云赞助支持的开源代理
https://mirrors.aliyun.com/goproxy //阿里云官方维护的go代理
https://goproxy.io //也是一个开源的go代理
参考链接: