当前位置:首页 > 文章列表 > Golang > Go教程 > go list -json 怎样查看包包含的嵌入文件

go list -json 怎样查看包包含的嵌入文件

来源:17golang原创 2026-10-13 02:10:26 0浏览 收藏

我第一次给静态资源检查器接入 Go 包时,原本想扫描源码里的 //go:embed,很快就遇到两个麻烦:模式不等于最终文件,而且测试包里的资源很容易被漏掉。更稳妥的入口是让 go list -json 直接输出包元数据。

先给结论:EmbedPatterns 记录普通包声明过的嵌入模式,EmbedFiles 记录这些模式实际匹配到的文件;测试代码则分别看 TestEmbed* 和 XTestEmbed*。用字段选择器请求这六组字段,就能把结果交给检查脚本。

官方文档:https://pkg.go.dev/cmd/go

先分清你要找的是模式,还是文件

这两个字段看起来相近,但用途不同。模式回答“源码声明了什么”,文件回答“工具链解析后认为哪些文件被包含”。例如 web/* 是模式,web/index.html 和 web/app.css 才是匹配文件。

go list JSON 中嵌入模式与实际文件清单的关系说明图
图1:从 go:embed 模式到 EmbedFiles 文件清单的字段关系说明图,不是运行截图。

如果检查器只关心“有哪些资源会进入包”,优先读取 EmbedFiles;如果还要提示模式过宽、模式变更或测试覆盖范围,再同时保留 EmbedPatterns。

先准备一个包含普通资源和测试资源的包

为了看清字段分组,可以准备一个很小的目录。普通包、同包测试和外部测试分别放一个嵌入声明:

package assets

import "embed"

// 普通包资源由 embed.FS 持有,供正式代码读取。
//go:embed web/*
var WebFiles embed.FS
package assets

import _ "embed"

// 同包测试资源会进入 TestEmbedPatterns 和 TestEmbedFiles。
//go:embed testdata/internal.txt
var internalFixture string
package assets_test

import _ "embed"

// 外部测试包资源会进入 XTestEmbedPatterns 和 XTestEmbedFiles。
//go:embed testdata/external.txt
var externalFixture string

这里的重点不是变量最后怎样使用,而是三类源文件的边界:普通 Go 文件、包内的 _test.go 文件,以及包外测试包的 _test.go 文件。

用 go list -json 查看普通包的嵌入文件

在模块根目录执行下面的命令。字段选择器让输出聚焦在嵌入信息,避免把依赖列表等无关包元数据一并交给后续脚本:

# 只请求六组嵌入字段,包路径按实际目录替换
go list -json=EmbedPatterns,EmbedFiles,TestEmbedPatterns,TestEmbedFiles,XTestEmbedPatterns,XTestEmbedFiles ./assets

普通包至少会关注下面两组字段。实际 JSON 中没有内容的字段可能不会出现,因此消费端不要把“字段缺失”直接当作错误:

{
  "EmbedPatterns": ["web/*"],
  "EmbedFiles": [
    "web/app.css",
    "web/index.html"
  ]
}

EmbedFiles 是相对包目录的文件名列表,适合做资源清单、许可证扫描或发布前的静态检查。它不是运行时读取结果,也不替代 embed.FS 的访问逻辑。

测试资源要看 TestEmbed 和 XTestEmbed

这是我后来补检查器时最容易漏掉的一点。包内测试文件产生 TestEmbedPatterns 与 TestEmbedFiles;外部测试包产生 XTestEmbedPatterns 与 XTestEmbedFiles。它们不会自动合并到普通包的 EmbedFiles 中。

go list 将普通包、包内测试和外部测试资源分组的结构示意图
图2:普通包、内部测试包和外部测试包对应不同 JSON 字段,是测试资源分组示意图。

想快速确认三组文件,可以把输出保留为 JSON,再按字段读取。不要只搜索所有文件名,因为同名资源可能来自不同测试组:

# 保存包元数据,后续脚本按字段区分正式资源与测试资源
go list -json=EmbedPatterns,EmbedFiles,TestEmbedPatterns,TestEmbedFiles,XTestEmbedPatterns,XTestEmbedFiles ./assets > package-embed.json

如果你的工具只需要打印摘要,也可以用模板减少人工阅读量:

# 只打印三类实际文件,空切片会保持为空
go list -f '{{.EmbedFiles}} {{.TestEmbedFiles}} {{.XTestEmbedFiles}}' ./assets

把 JSON 接入资源检查器时,按字段做三层判断

我会把检查逻辑拆成三步:先判断包是否成功加载,再收集普通包资源,最后按需追加两类测试资源。这样既不会把加载错误伪装成“没有嵌入”,也能让调用方选择是否纳入测试文件。

type EmbedInventory struct {
	EmbedFiles      []string
	TestEmbedFiles  []string
	XTestEmbedFiles []string
}

// mergeFiles 只合并已经由 go list 解析出的文件名,不重新扫描源码。
func mergeFiles(info EmbedInventory, includeTests bool) []string {
	files := append([]string{}, info.EmbedFiles...)
	if !includeTests {
		return files
	}
	files = append(files, info.TestEmbedFiles...)
	files = append(files, info.XTestEmbedFiles...)
	return files
}

上面这个结构只展示消费端的边界。真实调用还应保留 go list 的退出状态和标准错误:包加载失败、嵌入模式找不到匹配文件时,应该报告失败原因,而不是生成一个空清单。

几个容易误判的边界

现象应该怎样理解
只有 EmbedPatterns,没有 EmbedFiles先检查字段是否被请求;若请求了文件字段,再看模式是否匹配到文件。
普通包清单为空可能只是该包没有正式资源,不代表测试资源也为空。
测试文件没有出现在 EmbedFiles读取 TestEmbedFiles 或 XTestEmbedFiles,按测试包类型分别处理。
命令直接失败保留 stderr 和退出码;模式无匹配文件属于输入或包状态问题,不应静默吞掉。

还有一个实际取舍:发布清单通常只收集 EmbedFiles,测试报告则可以把两类测试字段并入结果。把这两个用途分开,输出会更容易读,也不容易把测试夹具误打进正式资源包。

最后的使用判断

如果目标是查看 Go 包到底包含哪些嵌入文件,优先记住这一条命令:

# 让 go 命令负责解析 embed 模式,再输出可供脚本消费的 JSON
go list -json=EmbedPatterns,EmbedFiles,TestEmbedPatterns,TestEmbedFiles,XTestEmbedPatterns,XTestEmbedFiles ./assets

只看正式资源时读 EmbedFiles;要覆盖测试夹具,再读 TestEmbedFiles 和 XTestEmbedFiles。对我来说,这比手工扫描 //go:embed 更稳定,因为“声明的模式”和“实际匹配的文件”都由同一个包加载过程给出。

相关问题:

  • 为什么不能只读取 EmbedPatterns? 因为模式是声明,文件清单才是解析后的具体结果。
  • 测试资源为什么要分两组? Go 区分包内测试文件和外部测试包,列表字段也保持了这个边界。
  • 是否应该把测试文件发布出去? 通常不应该;让检查器用开关决定是否把测试字段纳入分析。
版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
magisk能做什么不能做什么?Android定制工具的功能边界与合规使用说明magisk能做什么不能做什么?Android定制工具的功能边界与合规使用说明
上一篇
magisk能做什么不能做什么?Android定制工具的功能边界与合规使用说明
Go csv.Reader TrimLeadingSpace 处理字段前导空格的规则与引号边界
下一篇
Go csv.Reader TrimLeadingSpace 处理字段前导空格的规则与引号边界
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    446次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    517次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    532次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    478次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    303次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码