目录


Go包管理工具:前言

Golang一直存在一个被人诟病的问题是缺少一个官方的包依赖管理工具。从我个人的角度上来看存在两个问题:

  1. GOPATH特性对于多工程的情况下,支持不算友好。
  2. 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 有以下命令:

命令说明
downloaddownload modules to local cache(下载依赖包)
editedit go.mod from tools or scripts(编辑go.mod)
graphprint module requirement graph (打印模块依赖图)
initinitialize new module in current directory(在当前目录初始化mod)
tidyadd missing and remove unused modules(拉取缺少的模块,移除不用的模块)
vendormake vendored copy of dependencies(将依赖复制到vendor下)
verifyverify dependencies have expected content (验证依赖是否正确)
whyexplain 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 在不同平台上的安装路径
平  台GOPATH 默认值举 例
Windows 平台%USERPROFILE%/goC:\Users\用户名\go
Unix 平台$HOME/go/home/用户名/go

代理地址

https://goproxy.cn  //七牛云赞助支持的开源代理
https://mirrors.aliyun.com/goproxy  //阿里云官方维护的go代理
https://goproxy.io //也是一个开源的go代理

参考链接: