Go mod依赖管理工具

Go mod命令

用法:

1
2

go mod <command> [arguments]

command:

1
2
3
4
5
6
7
8
9

download 将依赖库下载到本地缓存
edit 编辑go.mod
graph 打印模块依赖图
init 再当前文件夹下初始化一个新的module, 创建go.mod文件
tidy 整理添加缺失并删除未使用的模块
vendor 将依赖复制到vendor下
verify 校验依赖
why 解释为什么需要依赖

1.go mod download [-json] [modules]

可以下载所需要的依赖,但是依赖并不是下载到GOPATH中,而是GOPATH/pkg/mod中,多个项目可以共享缓存的module。

2.go mod edit [editing flags] [go.mod]

  • -fmt 重新格式化go.mod文件而不进行其他更改。如'go mod edit -fmt'。

  • -module 更改模块的路径(go.mod文件的模块行)。

  • -require = path @ version和-droprequire = path 在给定的模块路径和版本上添加和删除需求。请注意,-require会覆盖路径上的所有现有require。这些标志主要用于了解模块图的工具。用户应该更喜欢'go get path @ version'或'go get path @ none',根据需要进行其他go.mod调整以满足其他模块施加的限制。

  • -exclude = path @ version和-dropexclude = path @ version 添加和删除给定模块路径和版本的排除项。请注意,如果排除已存在,则--exclude = path @ version是无效的。

  • -replace = old [@v] = new [@v]和-dropreplace = old [@v] 替换给定模块,如果省略old [@v]中的@v,则替换所有旧的模块版本。如果省略new[@v]中的@v,则为新路径应该是本地模块根目录,而不是模块路径。请注意,-replace会覆盖old[@v]的任何现有替换。

  • -require,-droprequire,-exclude,-dropexclude,-replace,可以重复-dropreplace编辑标志和更改按给定的顺序应用。

  • -go = version 设置Go语言版本。

  • -print 文本格式打印最终的go.mod而不是把它写回go.mod。

  • -json 以JSON格式打印最终的go.mod文件而不是把它写回go.mod。

3.go mod graph

4.go mod init [module]

5.go mod tidy [-v]

  • 删除不需要的依赖、新增需要的依赖,这个操作不会改变依赖版本。

6.go mod vendor [-v]

  • -v 打印vendored的名称模块。

7.go mod verify

8.go mod why [-m] [-vendor] packages...

Go mod配置GOPROXY

在国内是无法下载到golang.org/x ,使用go mod传统方式解决第三方包问题,go mod 提供了 replace 方式来手动替换包的地址。

这里使用代理可以解决这个麻烦的问题

主要有三个地址:

使用方法

1
2
3

export GOPROXY=https://goproxy.cn //linux
set GOPROXY=https://goproxy.cn //window,可以直接在环境变量中增加

goLand中设置方法

1
2
3
路径:GoLand —> Perferences —> Go —> Go Modules(vgo)—> Proxy
设置上面给出的地址
重启即可使用

goproxy.io是一个开源项目,当用户请求一个依赖库时,如果它发现本地没有这份代码就会自动请求源,然后cache到本地,用户就可以从 goproxy.io请求到数据。当然,这些都是在一个请求中完成的。goproxy.io只支持go module模式。当用户执行go get 命令时,会去检查$$GOPROXY//@v/list这个文件中是否有用户想要获取的版本,如果有,就依次获取 $$GOPROXY//@v/.info$$GOPROXY//@v/.mod$$GOPROXY//@v/.zip 等文件,如果没有就直接从源码库中去下载。

得益于 go module 在设计的时候非常重视安全这个领域,所以在启用了 go module 后,你会发现除了 go.mod 这个文件之外,还有一个 go.sum 文件,这个文件保存了每个依赖库的对应的hash值,来保证下载回来的代码库是正确的,不被人篡改的。同时,goproxy.io也是个开源的项目。可以自行部署到自己的IDC中,因为公司内部自己的代码库goproxy.io是无法访问到的。开源地址:https://github.com/goproxyio/goproxy

启动go mod

如果想更好的控制,可以修改 GO111MODULE 临时环境变量。

GO111MODULE 的取值为 off, on, or auto (默认值,因此前面例子里需要注意2个重点)。

  • off: GOPATH mode,查找vendor和GOPATH目录
  • on:module-aware mode,使用 go module,忽略GOPATH目录
  • auto:如果当前目录不在**$GOPATH**并且 当前目录(或者父目录)下有go.mod文件,则使用 GO111MODULE, 否则仍旧使用 GOPATH mode。

试试:

1
2
3
4
5
6
~/Code/Go/src/github.com/silenceshell/netproc$ GO111MODULE=on go build netproc.go
~/Code/Go/src/github.com/silenceshell/netproc$
~/Code/Go/src/github.com/silenceshell/netproc$ GO111MODULE=off go build netproc.go
netproc.go:7:2: cannot find package "github.com/gizak/termui" in any of:
/usr/local/go/src/github.com/gizak/termui (from $GOROOT)
/Users/silenceshell/Code/Go/src/github.com/gizak/termui (from $GOPATH)

on的时候因为我前面已经build过一次,所以直接成功了;但改为off时,会因为找不到包而报错。

注意,go modules 下载的包在 GOPATH/pkg/mod,这就是前面所说的 ‘maven way’;安装的命令仍在 GOPATH/bin

Go mod实战

如果要在GOPAHT中使用,则要设置GO111MODULE=on

初始化mod项目

1
2
3
4
mkdir -p ~/hello
cd ~/hello

go mod init github.com/you/hello

创建源文件

1
2
3
4
5
6
7
8
9
10
11
//hello.go
package main

import (
"fmt"
"rsc.io/quote"
)

func main() {
fmt.Println(quote.Hello())
}

编译项目

1
2
3
4
go build
./hello

Hello, world.