go modules
- 用法:
go mod <command> [arguments]
。 command
支持命令列表:
命令 go mod <command> |
作用 |
---|---|
go mod init |
生成 go.mod 文件 |
go mod download |
下载 go.mod 文件中指明的所有依赖 |
go mod tidy |
整理现有的依赖 |
go mod graph |
查看现有的依赖结构 |
go mod edit |
编辑 go.mod 文件 |
go mod vendor |
导出项目所有的依赖到vendor 目录 |
go mod verify |
校验一个模块是否被篡改过 |
go mod why |
查看为什么需要依赖某模块 |
go mod init
- 用法:
go mod init [module-path]
。 - 示例:
# 初始化当前目录并创建一个go.mod文件,模块路径根据其他条件推断判断
$ go mod init
# 初始化当前目录并创建一个go.mod文件,模块路径为example.com/m
$ go mod init example.com/m
- 介绍:
go mod init
命令在当前目录中初始化并写入一个新的go.mod
文件,实际上创建了一个以当前目录为根的新模块。go.mod
文件必须不存在时执行上面命令,否则会提示go.mod文件已存在提示。- 如当前存在一个空项目
demo
,在demo
目录下执行go mod init gitee.com/bms/demo
,会生成如下go.mod
文件,当前go
版本是go1.16.3
。
module gitee.com/bms/demo
go 1.16
init
接受一个可选参数,即新模块的模块路径,有关选择模块路径的说明,请参阅模块路径。- 如果省略了模块路径参数,
init
将尝试使用.go
文件、vendoring
工具配置文件和当前目录(如果在GOPATH
中)中的导入注释来推断模块路径。 - 如果存在
vendoring
工具的配置文件,init
将尝试从中导入模块需求。 init
支持以下配置文件:GLOCKFILE
(Glock)Godeps/Godeps.json
(Godeps)Gopkg.lock
(dep)dependencies.tsv
(godeps)glide.lock
(glide)vendor.conf
(trash)vendor.yml
(govend)vendor/manifest
(gvt)vendor/vendor.json
(govendor)
Vendoring
工具配置文件无法始终以完美的保真度进行翻译。- 例如,同一个仓库中的多个包在不同版本中导入,而仓库中只包含一个模块,那么导入的
go.mod
就只能需要一个版本的模块。 - 您可能希望运行
go list -m all
以检查构建列表中的所有版本,并运行go mod tidy
以添加缺少的需求并删除未使用的需求。
- 例如,同一个仓库中的多个包在不同版本中导入,而仓库中只包含一个模块,那么导入的
go mod download
- 将命名的模块下载到模块缓存中(模块缓存参考官方模块参考文档)。
- 参数可以是模块路径或模块模式,选择主模块的依赖项或表单的版本查询
path@version
。 - 不带参数,
download
适用于主模块的所有依赖项。 - 该
go
命令将在正常执行期间根据需要自动下载模块。 go mod download
命令主要用于预填充模块缓存或加载要由模块代理服务的数据。- 默认情况下,
download
不向标准输出写入任何内容。它将进度消息和错误打印到标准错误。
用法:
go mod download [-json] [-x] [modules]
-json
:
download
将一系列JSON对象打印到标准输出,描述每个下载的模块(或失败)type Module struct {
Path string // 模块路径
Version string // 模块版本
Error string // 错误模板描述
Info string // 缓存的 .info 文件的绝对路径
GoMod string // 缓存 .mod 文件的绝对路径
Zip string // 缓存的 .zip 文件的绝对路径
Dir string // 缓存源根目录的绝对路径
Sum string // checksum路径,版本(比如在go.sum)
GoModSum string // go.mod的checksum(比如在go.sum)
-x
:download
打印命令download
执行到标准错误
- 示例:
$ go mod download -json -x gitee.com/phpbms/demo
{
"Path": "gitee.com/phpbms/demo",
"Version": "v0.0.0-20211021090521-71a745ffbccb",
"Info": "/mnt/g/Go/worker/pkg/mod/cache/download/gitee.com/phpbms/demo/@v/v0.0.0-20211021090521-71a745ffbccb.info",
"GoMod": "/mnt/g/Go/worker/pkg/mod/cache/download/gitee.com/phpbms/demo/@v/v0.0.0-20211021090521-71a745ffbccb.mod",
"Zip": "/mnt/g/Go/worker/pkg/mod/cache/download/gitee.com/phpbms/demo/@v/v0.0.0-20211021090521-71a745ffbccb.zip",
"Dir": "/mnt/g/Go/worker/pkg/mod/gitee.com/phpbms/demo@v0.0.0-20211021090521-71a745ffbccb",
"Sum": "h1:JJlXgKY8MUQtOlnSHtbIsHtRU9DNbxx9NUgpsDt3pQA=",
"GoModSum": "h1:6H8vzSoXg8Ey2gdfFaP7ToLmbOnfc04IAcuTFDKqSV8="
}
go mod tidy
go mod tidy
确保go.mod
文件与模块中的源代码匹配。- 它添加了构建当前模块的包和依赖项所需的任何缺失的模块要求,并删除了对不提供任何相关包的模块的要求。
- 它还向
go.sum
添加任何缺失的条目并删除不必要的条目。
go mod tidy
通过递归加载主模块中的所有包以及它们导入的所有包来工作,这包括测试导入的包(包括其他模块中的测试)。go mod tidy
就像启用了所有构建标记一样,因此它会考虑特定于平台的源文件和需要自定义构建标记的文件,即使这些源文件通常不会被构建。- 有一个例外:忽略构建标记未启用,因此不会考虑具有构建约束【
// +build ignore
】的文件。 - 请注意,
go mod tidy
不会考虑主模块中名为testdata
或名称以.
或_
除非这些包是由其他包显式导入的。 - 一旦
go mod tidy
加载了这组包,它会确保提供一个或多个包的每个模块在主模块的go.mod
文件中都有一个require
指令,或者如果主模块在go 1.16
或更低版本 - 是必需的另一个必需的模块。 go mod tidy
将添加对每个缺失模块的最新版本的要求(有关最新版本的定义,请参阅版本查询),go mod tidy
将删除不提供上述集合中任何包的模块的require
指令。go mod tidy
还可以添加或删除require
指令的// indirect
,// indirect
间接注释表示模块不提供由主模块中的包导入的包。- 用法:
go mod tidy [-e] [-v] [-go=version] [-compat=version]
。 - 介绍:
-e
:(在Go 1.16
中添加)在加载包时遇到错误时尝试继续。-v
:将有关已删除模块的信息打印到标准错误。-go=
:将go
指令更新为指定的版本,根据该版本启用或禁用模块图修剪和延迟模块加载(并根据需要添加或删除// indirect
间接注释)。-compat=
:当模块图由go
指令中指示的版本之前的Go
版本加载时,go mod tidy
将检查所选版本的模块是否不会更改。还可以通过-compat
标志显式指定版本检查的兼容性。
go mod graph
- 以文本形式打印模块需求图。
- 用法:
go mod graph [-go=version]
。 - 介绍:
- 模块图中的每个顶点代表一个模块的特定版本,图中的每条边代表对依赖项的最低版本的要求。
go mod graph
打印图形的边缘,每行一个。- 每行有两个空格分隔的字段:模块版本及其依赖项之一。
- 每个模块版本都标识为
path@version
形式的字符串。 - 主模块没有
@version
后缀,因为它没有版本。
- -go=:
go mod graph
报告给定Go
版本加载的模块图,而不是go.mod
文件中的go
指令指示的版本。 - 有关如何选择版本的更多信息,请参阅最小版本选择(
MVS
)。- 另请参阅
go list -m
以打印选定的版本,并查看go mod why
以了解为什么需要模块。
- 另请参阅
example.com/main example.com/a@v1.1.0
example.com/main example.com/b@v1.2.0
example.com/a@v1.1.0 example.com/b@v1.1.1
example.com/a@v1.1.0 example.com/c@v1.3.0
example.com/b@v1.1.0 example.com/c@v1.1.0
example.com/b@v1.2.0 example.com/c@v1.2.0
go mod edit
- 该命令提供了一个用于编辑和格式化
go.mod
文件的命令行界面,主要供工具和脚本使用。 go mod edit
只读取一个go.mod
文件,它不查找有关其他模块的信息。- 默认情况下,
go mod edit
读取和写入go.mod
主模块的文件,但可以在编辑标志后指定不同的目标文件。
用法:
go mod edit [editing flags] [-fmt|-print|-json] [go.mod]
editing flags
可以重复使用,按给定的顺序)
go.mod
文件的module
行),修改module
行模块名称。go.mod
文件的Go
版本。go.mod
上的任何现有要求path
。-exclude=path@version
如果该排除已存在, 则为空操作。
old@v
则添加左侧没有版本的替换,这适用于旧模块路径的所有版本。new@v
则新路径应该是本地模块根目录,而不是模块路径。-replace
覆盖的任何冗余替换old[@v]
,因此省略@v
将删除特定版本的替换。
@v
提供了,则删除给定版本的替换,左侧没有版本的现有替代品仍可更换模块。@v
省略 ,则删除没有版本的替换。v1.2.3
)或间隔(等[v1.1.0,v1.2.0]
)。
-retract
标志不能为retract
指令添加基本原理注释。
go.mod
文件而不进行其他更改。
go.mod
文件的任何其他修改也暗示了这种重新格式化。go mod edit -fmt
。go.mod
以其文本格式打印final ,而不是将其写回磁盘(就是打印go.mod
文件内容)。go.mod
以 JSON 格式打印最终结果,而不是以文本格式将其写回磁盘go mod edit -json
。// json打印格式
{
"Module": {
"Path": "mymod"
},
"Go": "1.17",
"Require": [
{
"Path": "gitee.com/phpbms/demo",
"Version": "v0.0.0-20211021090521-71a745ffbccb",
"Indirect": true
}
],
"Exclude": null,
"Replace": null,
"Retract": null
}
// 对应相关结构体
type Module struct {
Path string
Version string
}
type GoMod struct {
Module Module
Go string
Require []Require
Exclude []Module
Replace []Replace
}
type Require struct {
Path string
Version string
Indirect bool
}
type Replace struct {
Old Module
New Module
}
type Retract struct {
Low string
High string
Rationale string
}
- 示例:
# 添加替换指令
$ go mod edit -replace example.com/a@v1.0.0=./a
# 删除替换指令
$ go mod edit -dropreplace example.com/a@v1.0.0
# 设置go版本,添加需求,打印文件而不是写入磁盘
$ go mod edit -go=1.14 -require=example.com/m@v1.0.0 -print
# 格式化 go.mod 文件
$ go mod edit -fmt
# 格式化并打印不同的 .mod 文件
$ go mod edit -print tools.mod
# 打印 go.mod 文件的 JSON 表示
$ go mod edit -json
# 所有命令使用
$ go mod edit -module=mydemo1 -go=1.16 -require=gitee.com/phpbms/demo/v3@v3.0.0 -exclude=gitee.com/phpbms/demo/v3@v3.0.1 -replace=gitee.com/phpbms/demo/v2@v2.0.1=gitee.com/phpbms/demo/v2@v2.0.0 -retract=v1.1.1 -print ./go.mod
# 修改go版本,从之前的 go 1.20 修改为 go 1.21rc2
$ go mod edit -go 1.21rc2
go mod vendor
- 在主模块的根目录中构造一个名为
vendor
的目录,该目录包含支持主模块中包的构建和测试所需的所有包的副本。- 不包括仅通过主模块之外的包测试导入的包。
- 与
go mod tidy
和其他模块命令一样,在构建vendor
目录时不考虑除了ignore
之外的构建约束。
- 当启用
vendoring
时,go
命令将从vendor
目录加载包,而不是将模块从其源下载到模块缓存中,并使用那些下载副本的包。 go mod vendor
还会创建文件vendor/modules.txt
,其中包含vendor
包的列表以及从中复制它们的模块版本。- 当启用
vendoring
时,此清单用作模块版本信息的来源,如go list -m
和go version -m
所报告的。 - 当
go
命令读取vendor/modules.txt
时,它会检查模块版本是否与go.mod
一致。 - 如果
go.mod
在vendor/modules.txt
生成后发生了变化,则应再次运行go mod vendor
。
- 当启用
- 请注意,
go mod vendor
会在重新构建之前删除vendor
目录(如果它存在)。- 不应对
vendor
的软件包进行本地更改。 go
命令不会检查vendor
目录中的包是否未被修改,但是可以通过运行go mod vendor
并检查没有进行任何更改来验证vendor
目录的完整性。
- 不应对
- 使用:
go mod vendor [-e] [-v]
。- -e:(在
Go 1.16
中添加)在加载包时遇到错误时尝试继续。 - -v:将
vendor
模块和包的名称打印为标准错误。
- -e:(在
go mod verify
- 检查存储在模块缓存中的主模块的依赖项自下载以来没有被修改。
- 执行此检查,对每个下载的
module.zip
文件和提取的目录进行散列然后将这些散列与首次下载模块时记录的散列进行比较。 go mod verify
检查构建列表中的每个模块(可以使用go list -m all
打印所有模块)。- 如果所有模块都未修改,则
go mod verify
打印all modules verified
否则,它将报告哪些模块已更改并以非零状态退出。 - 注意:所有模块感知命令都会验证主模块的
go.sum
文件中的哈希值是否与为下载到模块缓存中的模块记录的哈希值匹配。 - 如果
go.sum
中缺少哈希(例如,因为模块是第一次使用),则go命令使用校验和数据库验证其哈希。- 除非模块路径与
GOPRIVATE
或GONOSUMDB
匹配。
- 除非模块路径与
go mod verify
不会为不在缓存中的模块下载内容,也不会使用go.sum
文件来验证模块内容。- 但是,
go mod verify
可能会下载go.mod
文件以执行最少的版本选择。 - 它将使用
go.sum
来验证这些文件,并且可能会为丢失的哈希添加go.sum
条目。 - 用法:
go mod verify
。
$ go mod verify
all modules verified
go mod why
go mod why
在导入图中显示从主模块到每个列出的包的最短路径。- 用法:
go mod why [-m] [-vendor] packages...
。- -m:
go mod why
将其参数视为模块列表。go mod why
会打印每个模块中任何包的路径。- 请注意,即使使用
-m
,go mod why
查询包图,而不是go mod graph
打印的模块图。
- -vendor:
go mod why
忽略主模块之外的包测试中的导入(就像go mod vendor
所做的那样)。- 默认情况下,
go mod why
会考虑与all
模式匹配的包图。 - 这个标志在
Go 1.16
之后在声明go 1.16
或更高版本的模块中无效(使用go.mod
中的go
指令),因为all
的含义已更改以匹配go mod
供应商匹配的包集。
- 默认情况下,
- -m:
- 示例:
- 输出是一个节序列,每个在命令行上命名的包或模块都有一个节,用空行分隔。
- 每节以注释行开头,以
#
开头,给出目标包或模块。 - 后续行给出了通过导入图的路径,每行一个包。
- 如果包或模块不是从主模块引用的,则该节将显示一个带括号的注释,表明该事实。
$ go mod why golang.org/x/text/language golang.org/x/text/encoding
# golang.org/x/text/language
rsc.io/quote
rsc.io/sampler
golang.org/x/text/language
# golang.org/x/text/encoding
(main module does not need package golang.org/x/text/encoding)