go包管理工具小结

go dep

安装

执行以下命令安装godep工具。

go get github.com/tools/godep

基本命令

安装好godep之后,在终端输入godep查看支持的所有命令。

godep save     将依赖项输出并复制到Godeps.json文件中
godep go       使用保存的依赖项运行go工具
godep get      下载并安装具有指定依赖项的包
godep path     打印依赖的GOPATH路径
godep restore  在GOPATH中拉取依赖的版本
godep update   更新选定的包或go版本
godep diff     显示当前和以前保存的依赖项集之间的差异
godep version  查看版本信息

使用godep help [command]可以看看具体命令的帮助信息。

使用godep
在项目目录下执行godep save命令,会在当前项目中创建Godeps和vender两个文件夹。

其中Godeps文件夹下有一个Godeps.json的文件,里面记录了项目所依赖的包信息。 vender文件夹下是项目依赖的包的源代码文件。

go dep开发流程

保证程序能够正常编译

执行godep save保存当前项目的所有第三方依赖的版本信息和代码

提交Godeps目录和vender目录到代码库。

如果要更新依赖的版本,可以直接修改Godeps.json文件中的对应项

vender机制

Go1.5版本之后开始支持,能够控制Go语言程序编译时依赖包搜索路径的优先级。

例如查找项目的某个依赖包,首先会在项目根目录下的vender文件夹中查找,如果没有找到就会去$GOAPTH/src目录下查找。

##go module
go module是Go1.11版本之后官方推出的版本管理工具,并且从Go1.13版本开始,go module将是Go语言默认的依赖管理工具。

go mod命令

常用的go mod命令如下:

go mod download    下载依赖的module到本地cache(默认为$GOPATH/pkg/mod目录)
go mod edit        编辑go.mod文件
go mod graph       打印模块依赖图
go mod init        初始化当前文件夹, 创建go.mod文件
go mod tidy        增加缺少的module,删除无用的module
go mod vendor      将依赖复制到vendor下
go mod verify      校验依赖
go mod why         解释为什么需要依赖

module用来定义包名
require用来定义依赖包及版本
indirect表示间接引用

GOPROXY

GOPROXY 的默认值是:

https://proxy.golang.org,direct

这有一个很严重的问题,就是 proxy.golang.org 在国内是无法访问的,
因此这会直接卡住你的第一步,所以你必须在开启 Go modules 的时
,同时设置国内的 Go 模块代理,执行如下命令:

$ go env -w GOPROXY=https://goproxy.cn,direct

命令行开启 Go Modules

目前 Go modules 并不是默认开启,因此Go语言提供了 GO111MODULE 这个环境变量来作为 Go modules 的开关,其允许设置以下参数:

  • auto:只要项目包含了 go.mod 文件的话启用 Go modules,目前在Go1.11至 Go1.14 中仍然是默认值。
  • on:启用 Go modules,推荐设置,将会是未来版本中的默认值。
  • off:禁用 Go modules,不推荐设置。

如果你不确定你当前的值是什么,可以执行go env命令,查看结果:

$ go env
GO111MODULE="off"

如果需要对 GO111MODULE 的值进行变更,推荐通过go env命令进行设置:

$ go env -w GO111MODULE=on

goland中启用go module

代理可以设置为:https://goproxy.cn

初始化项目

go mod init

go.mod 文件

在初始化项目时,会生成一个 go.mod 文件,是启用了 Go modules 项目所必须的最重要的标识.

示例:

module github.com/example
go 1.13

require (
    github.com/jinzhu/gorm v1.9.12 // indirect
)
exclude github.com/jinzhu/gorm v1.9.11
replace github.com/go-kit/kit v0.9.0 => github.com/go-kit/kit v0.8.0
  • module:用于定义当前项目的模块路径。
  • go:用于标识当前模块的 Go 语言版本,值为初始化模块时的版本,升级golang版本时,要注意是否需要更改此处
  • require:用于设置一个特定的模块版本。
  • exclude:用于从使用中排除一个特定的模块版本。
  • replace:用于将一个模块版本替换为另外一个模块版本

go.sum 文件

go.sum 文件详细罗列了当前项目直接或间接依赖的所有模块版本,并写明了那些模块版本的 SHA-256 哈希值以备 Go 在今后的操作中保证项目所依赖的那些模块版本不会被篡改。

cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
....

h1 hash 是 Go modules 将目标模块版本的 zip 文件开包后,针对所有包内文件依次进行 hash,然后再把它们的 hash 结果按照固定格式和算法组成总的 hash 值。

而 h1 hash 和 go.mod hash 两者,要不就是同时存在,要不就是只存在 go.mod hash。那什么情况下会不存在 h1 hash 呢,就是当 Go 认为肯定用不到某个模块版本的时候就会省略它的 h1 hash,就会出现不存在 h1 hash,只存在 go.mod hash 的情况。

替代包

在管理过程中,导入的包为 0.9.0 版本,实际需要0.8.0版本,需要将导入的0.9.0版本
replace替代为 0.8.0 版本

go 1.13

require (
    github.com/jinzhu/gorm v1.9.12 // indirect
)
replace github.com/go-kit/kit v0.9.0 => github.com/go-kit/kit v0.8.0

也可以用命令行模式:

1
go mod edit -replace=old[@v]=new[@v]

参考资料:

学习 Go Modules 这一篇就够:终极入门