能,go-licenses可输出依赖的spdx许可证标识(如gpl-2.0-only),但不直接标注“gpl”,需用户对照spdx列表判断传染性;它默认仅扫描实际编译依赖,未使用模块需加--include-submodules;拦截高风险许可证须配合jq等工具解析其json输出。

go-licenses 能不能直接查出 GPL 依赖?
不能直接标记“GPL”,它只输出每个依赖声明的许可证文本文件和 SPDX ID,比如 GPL-2.0-only 或 GPL-3.0-or-later。你得自己比对 SPDX 官方列表(如 https://spdx.org/licenses/)确认是否属于传染性许可证。常见陷阱是把 GPL-2.0-only 和 GPL-2.0-or-later 当成一回事——后者允许升版到 GPLv3,前者严格锁定为 v2。
执行命令后生成的许可证文件夹里,每个子目录对应一个依赖模块,里面包含 LICENSE 或 NOTICE 原文。重点看三点:
- 文件名是否为标准命名(
LICENSE、LICENSE.txt、COPYING),非标文件名可能被go-licenses忽略 - 内容开头是否有明确 SPDX 标识行,例如
SPDX-License-Identifier: GPL-3.0-or-later - 是否存在多许可证声明(如
MIT OR Apache-2.0),这种“OR”关系需按最严条款处理
go mod graph 里看到 github.com/some/lib,但 go-licenses 没扫出来
说明该模块没被实际编译进最终二进制,只是间接出现在依赖图中。Go 的 go-licenses 默认只扫描 go list -m all 中“active”状态的模块,即至少有一个包被 import 的依赖。静默未使用的模块不会触发许可证收集。
要强制检查所有图中节点,加 --include-submodules 参数:
go-licenses save . --save_path=third_party_licenses --include-submodules
但注意:这会把测试用、构建工具类依赖(如 golang.org/x/tools)也拉进来,增大审查范围。真正需要关注的是 runtime 依赖——运行时实际加载的那些。
CI 流程里怎么自动拦截 AGPL 依赖?
靠 go-licenses 自身做不到拦截,它不提供 exit code 或结构化输出。必须配合脚本解析其 JSON 输出:
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 先用
go-licenses json . > licenses.json生成结构化数据 - 用
jq提取所有license字段,匹配AGPL、SSPL、CC-BY-SA等高风险项 - 发现匹配就
exit 1中断 CI
示例判断逻辑(Bash):
jq -r '.[] | select(.license | contains("AGPL") or contains("SSPL")) | .module' licenses.json | head -1 | grep -q "." && echo "BLOCKED: AGPL/SSPL found" && exit 1
别忘了在 CI 中设置 GOSUMDB=off 是危险操作——它会让 go-licenses 读不到真实校验和,导致许可证文件来源不可信。
replace 后的私有 fork 还算原许可证吗?
不算。一旦用 replace github.com/real/lib => ./local-fix,go-licenses 就只读取本地目录里的 LICENSE 文件,完全忽略原仓库声明。如果 fork 没复制原 LICENSE,或改了条款,合规风险立刻转嫁到你头上。
正确做法只有两种:
- 保持 fork 与上游许可证一致,并在本地
LICENSE文件首行注明“Based on github.com/real/lib, licensed under GPL-3.0-or-later” - 若做了实质性修改(如重写核心算法),必须重新评估新代码的许可证兼容性——哪怕原库是 MIT,你的修改也可能触发 GPL 传染
最容易被忽略的是 vendor 目录:如果项目还保留了旧式 vendor/,go-licenses 默认不扫描它,得手动加 --force-vendor 参数,否则私有依赖的许可证就彻底隐身了。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










