应先用go list -m -json all提取模块路径,再结合licensecheck扫描LICENSE等文件识别SPDX ID,对UNKNOWN结果人工复核,并用grep -E筛选GPL等高风险条款,最终生成带模块路径、许可证ID和传染性标记的CSV报告。

如何用 go list 提取模块依赖树并过滤出含许可证声明的路径
直接跑 go list -m -json all 会输出所有模块(包括间接依赖),但默认不带许可证字段。Go 官方至今没在 go mod 元数据中标准化许可证字段,所以不能靠 License 字段直接筛选——得从 go.mod 所在目录里找 LICENSE、LICENSE.md 等文件,再结合 go list 输出的 Dir 路径做本地扫描。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 先用
go list -m -json all 2>/dev/null | jq -r '.Dir'提取所有模块源码路径,去重后逐个检查是否存在常见许可证文件 - 跳过
golang.org/x/和std模块——它们走 Go 项目统一协议(BSD-3-Clause),无需重复校验 - 注意
replace指令会影响Dir路径,实际扫描时得优先读取go.mod中的replace声明,否则可能扫错目录
为什么不能只依赖 github.com/google/licensecheck 的自动识别结果
这个工具能解析文本内容并匹配许可证模板,但对多层嵌套依赖容易漏判:比如某个模块的 LICENSE 文件写的是 “Apache-2.0 with LLVM exception”,而 licensecheck 默认只认标准 SPDX ID,会标为 UNKNOWN;更麻烦的是,有些模块把许可证放在 NOTICE 或 THIRD-PARTY-LICENSES 里,工具默认不查这些文件名。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 用
licensecheck -f LICENSE -f NOTICE -f THIRD-PARTY-LICENSES显式指定扫描文件列表 - 对识别结果为
UNKNOWN的模块,保留其Dir路径,后续人工复核——别直接丢弃 - 避免用
-r(递归)模式扫整个$GOPATH/pkg/mod,会产生大量重复和无效路径,拖慢速度且干扰判断
如何用 Bash + jq 快速生成可审计的依赖许可证报告
最终目标不是“有没有许可证”,而是“哪些模块用了 GPL-2.0-only 这类高风险条款”。需要把模块路径、识别出的 SPDX ID、是否含传染性条款标记出来,方便法务介入。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 用
jq把go list和licensecheck结果 join 起来:go list -m -json all 2>/dev/null | jq -r 'select(.Replace == null) | "\(.Path)\t\(.Dir)"' | while IFS=$'\t' read mod dir; do echo -e "$mod\t$(licensecheck -f LICENSE -f NOTICE "$dir" 2>/dev/null | head -n1)"; done | sort -u
- 用
grep -E "(GPL|AGPL|CPAL|SSPL)"过滤高风险关键词,但别只信字符串匹配——比如MIT后面跟着with GPL-3.0 linking exception就得单独标出 - 输出 CSV 时用
printf "%q"包裹字段,避免模块名含逗号或换行导致 Excel 解析错位
为什么 go mod graph 不适合直接用于许可证风险定位
go mod graph 只输出模块引用关系(A → B),但许可证风险不取决于“谁调用了谁”,而取决于“哪个模块自身声明了什么许可证”。比如 A 是 MIT,它依赖的 B 是 GPL-3.0,那真正触发风险的是 B,而不是 A 的调用链。用图结构强行标注风险,反而模糊了责任主体。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 把
go mod graph当作辅助验证手段:发现某模块被多个上游引用时,它的许可证问题影响面更大,需优先处理 - 别在图上做许可证合并计算(如“父模块 MIT + 子模块 GPL = 混合风险”)——Go 没有“组合许可证”概念,每个模块独立承担合规责任
- 如果项目用了
replace指向 fork 仓库,必须手动确认该 fork 是否修改了原许可证——go mod graph完全不体现这种变更
真正卡点在于许可证文本的语义解析,不是依赖关系拓扑。自动化脚本能帮你收拢路径、提取文件、粗筛关键词,但最后一道“这段文字到底允不允许静态链接”还得人来读。


















