composer licenses 命令默认输出纯文本表格,列宽动态、无结构,易因换行或空格导致解析错误;应改用 --format=json 输出结构化 JSON(含 name、license、homepage 等稳定字段),再用 jq 等工具安全解析,避免字符串匹配陷阱。

composer licenses 输出格式不统一,直接解析容易出错
Composer 自带的 composer licenses 命令输出是纯文本表格,列宽动态变化、无结构化字段,用 grep 或 awk 硬切分极易因包名含空格、许可证名换行或对齐错位而漏判或误判。比如 MIT 可能被截成 MI 和 T 两行,BSD-3-Clause 在窄终端里也可能折行。
真正可用的方式是改用 JSON 输出(Composer 2.2+ 支持):
composer licenses --format=json > licenses.json
再用
jq 或任意 JSON 解析器处理。这样每项都含 name、license、homepage 等稳定字段,避免字符串匹配陷阱。
- 旧版 Composer(
-
--format=json不会自动校验许可证有效性,只是把原始数据转成 JSON - 注意:某些包的
license字段可能是数组(如["MIT", "Apache-2.0"]),需遍历判断是否至少一项在白名单内
白名单配置应区分“允许”与“需人工复核”两类许可证
合规审批不是非黑即白。比如 GPL-2.0-only 在闭源项目中不可用,但内部工具类项目可能允许;Unlicense 法律效力在部分司法辖区存疑,宜标记为“需复核”。白名单不应是扁平列表,而应带语义分级。
推荐用 YAML 定义白名单文件 license-whitelist.yml:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
allowed: - MIT - BSD-2-Clause - BSD-3-Clause - Apache-2.0 review_required: - GPL-2.0-only - GPL-3.0-only - AGPL-3.0-only - Unlicense
- 脚本读取该文件后,对每个依赖的
license字段逐项比对:先查allowed,命中则跳过;再查review_required,命中则记录并退出非零码 - 不要把
proprietary或空字符串当作合法许可证——这些应直接拒绝,不进白名单也不进复核列表 - 注意大小写:Composer 输出的许可证名通常是大写(如
MIT),但有些包写成mit或Mit,建议统一转大写再比对
CI 中集成时必须检查 dev-dependencies 是否混入生产许可证风险
composer licenses 默认包含 require-dev 的包,而开发依赖(如 phpunit、mockery)的许可证可能宽松,但若其代码意外打入生产构建(比如通过 class_alias 或打包脚本引入),仍可能触发合规问题。
- CI 脚本应显式分离:用
composer install --no-dev后再跑许可证检查,或用jq过滤掉dev: true的条目 - 更稳妥的做法是生成两份报告:一份全量(用于审计),一份仅
require(用于准入卡点) - 某些包(如
symfony/console)在require和require-dev中版本不同,许可证也可能不同,不能只看锁文件顶层声明
自动化审批失败时要给出可定位的上下文,而非仅报错
单纯返回 ERROR: found disallowed license GPL-3.0-only in package foo/bar 不够。开发者需要立刻知道:这个包是哪一层引入的?是否间接依赖?能否升级到宽松许可证版本?
建议在检测脚本中补全依赖路径:
composer depends --tree foo/bar 2>/dev/null | head -n 5
- 配合
composer show foo/bar查license字段确认实际值,避免被composer.json中错误的声明误导 - 如果白名单支持别名映射(如把
BSD-3-Clause映射到BSD-3),日志中应明确写出“匹配别名”,方便审计追溯 - 最易忽略的是私有包:它们的
license字段常为空或填proprietary,这类必须人工确认,且不能靠白名单绕过


















