文章目录
- 1.简介
- 2.基本语法
- 2.1 格式
- 2.2 常用包路径写法
- 2.3 默认输出
- 2.4 结构化输出
- 2.5 模块模式格式
- 3. 选项
- 3.1 输出控制
- 3.2 范围控制
- 3.3 模块模式
- 3.4 常用模板字段
- 4. 示例
- 5. 常见问题
- 5.1 `./...` 与 `...` 有什么区别?
- 5.2 模板中的 `{{}}` 需要转义吗?
- 5.3 `-e` 会掩盖真正的错误吗?
- 5.4 如何只查看某个包的直接依赖?
- 6. 小结
- 参考文献
1.简介
go list的核心作用是以可编程的方式输出 Go 包和模块的信息。
它的典型用途包括:
- 确认某个包是否存在
- 列出项目的所有依赖
- 查看依赖是否有可用更新
- 导出包或模块的元数据供脚本处理
与go build、go run不同,go list不编译代码,只做解析和查询,因此速度极快,非常适合嵌入脚本或 CI 流程。
go list有两种工作模式:
| 模式 | 触发方式 | 操作对象 |
|---|---|---|
| 包模式 | 默认 | 包(package) |
| 模块模式 | 加-m | 模块(module) |
2.基本语法
2.1 格式
go list[-f format][-json][-m][list flags][build flags][packages]不带参数时,go list列出当前目录的包信息。
2.2 常用包路径写法
| 写法 | 含义 |
|---|---|
go list | 当前目录的包 |
go list ./... | 当前项目及所有子目录的包 |
go list ... | 工作区所有包 |
go list hash | 标准库hash包 |
go list github.com/gin-gonic/gin | 外部包 |
2.3 默认输出
最简单的输出是导入路径:
$ go list github.com/gin-gonic/gin github.com/gin-gonic/gin2.4 结构化输出
go list的真正价值在于结构化输出,有两种方式:
JSON 格式:
go list-jsonhash输出包的所有元数据,包括Dir、ImportPath、Name、GoFiles、Imports、Deps、Doc等字段。
Go 模板格式:
go list-f'{{.ImportPath}}: {{.Dir}}'hash输出:
hash: /usr/local/go/src/hash2.5 模块模式格式
加-m后,操作对象变为模块:
go list-mall# 列出所有模块go list-m-jsongin# 以 JSON 输出某模块信息3. 选项
3.1 输出控制
| 选项 | 作用 |
|---|---|
-json | 以 JSON 格式输出 |
-f | 用 Go 模板自定义输出格式 |
3.2 范围控制
| 选项 | 作用 |
|---|---|
-deps | 同时列出所有依赖 |
-test | 包含测试相关文件信息 |
-e | 遇到错误也继续处理,不中断 |
3.3 模块模式
| 选项 | 作用 |
|---|---|
-m | 切换到模块模式 |
-u | 配合-m,检查可用更新 |
-versions | 配合-m,列出所有可用版本 |
3.4 常用模板字段
| 字段 | 含义 |
|---|---|
{{.ImportPath}} | 导入路径 |
{{.Name}} | 包名 |
{{.Dir}} | 包所在目录 |
{{.GoFiles}} | Go 源文件列表 |
{{.Imports}} | 直接依赖 |
{{.Deps}} | 所有依赖(含间接) |
各选项的具体用法与组合方式,见第 4 章示例。
|{{.Doc}}| 包文档摘要 |
join是 Go 模板内置函数,用于把切片拼成字符串,例如{{join .Deps "\n"}}。
4. 示例
(1)确认包是否存在。
go list github.com/go-sql-driver/mysql存在则输出导入路径,不存在则报错。
在脚本中判断:
ifgo list github.com/foo/bar>/dev/null2>&1;thenecho"包存在"elseecho"包不存在"fi(2)查看模块的可用版本列表。
go list-m-versions<mod-path>比如查看 gin 框架的可用版本。
go list-m-versionsgithub.com/gin-gonic/gin github.com/gin-gonic/gin v1.1.1 v1.1.2 v1.1.3 v1.1.4 v1.3.0 v1.4.0 v1.5.0 v1.6.0 v1.6.1 v1.6.2 v1.6.3 v1.7.0 v1.7.1 v1.7.2 v1.7.3 v1.7.4 v1.7.5 v1.7.6 v1.7.7 v1.8.0 v1.8.1 v1.8.2 v1.9.0 v1.9.1 v1.10.0 v1.10.1 v1.11.0 v1.12.0(3)列出项目的所有直接依赖。
go list-f'{{join .Imports "\n"}}'./...|sort-u(4)列出某个包的所有依赖。
go list-f'{{join .Deps "\n"}}'hash(5)导出依赖树为 JSON。
go list-json-deps./...>deps.json后续可用jq等工具分析。
(6)列出所有模块
go list-mall列出所有模块指的是列出当前项目的主模块,以及它依赖的所有模块(包括直接依赖和间接依赖)。
这里的-m是关键:它把 go list 的操作对象从“包(package)”切换成“模块(module)”。all 则是一个特殊模式,表示“主模块 + 全部依赖模块”。
(7)检查依赖更新
go list-m-uall输出中会标注可用更新:
github.com/gin-gonic/gin v1.10.0 [v1.10.1](8)格式化输出依赖更新。
go list-m-u-f'{{.Path}} {{.Version}} -> {{.Update.Version}}'all输出:
github.com/gin-gonic/gin v1.10.0 -> v1.10.1(9)查看某模块的详细信息
go list-m-jsongithub.com/gin-gonic/gin输出模块的Path、Version、Time、Dir、GoMod等字段。
(10)找出依赖了某个包的所有包
go list-f'{{.ImportPath}} {{join .Deps " "}}'./...|grep"golang.org/x/sync"(11)宽容模式处理错误
go list-e-json./...5. 常见问题
5.1./...与...有什么区别?
./...匹配当前目录及其子目录下的包;...匹配当前工作区(workspace)内的所有包,范围更大。
在单模块项目中两者通常等价,但在多模块工作区中差异明显,建议按需选择。
5.2 模板中的{{}}需要转义吗?
在 shell 中直接使用-f '{{.ImportPath}}'时,单引号可避免 shell 展开。若在脚本中拼接模板,注意$等字符的转义。
5.3-e会掩盖真正的错误吗?
-e让go list遇到无法解析的包时继续输出,适合排查不稳定项目。但正常开发中建议先去掉-e,让错误直接暴露,便于定位问题。
5.4 如何只查看某个包的直接依赖?
用{{.Imports}}(直接依赖)而非{{.Deps}}(含间接依赖),例如:
go list-f'{{join .Imports "\n"}}'hash6. 小结
go list的核心价值是把 Go 的包和模块信息变成可编程的数据:
- 包模式:
go list <pkg>查询包信息,配合-json或-f输出结构化数据 - 模块模式:
go list -m切换视角,管理依赖、检查更新 - 脚本友好:配合
grep、jq、sort做自动化分析 - 不编译代码:只解析元数据,速度快,适合 CI 和脚本
掌握go list,你就能用命令行快速回答“这个包在哪”“依赖了什么”“有没有更新”等问题,无需打开 IDE 或手动翻go.mod。
参考文献
- Go 官方文档:go list
- Go Modules Reference
- pkg.go.dev 包查询