Composer如何导出所有依赖包的许可证清单?(合规性检查)

5次阅读

应使用 composer show –licenses –recursive –format=json 导出全部依赖许可证,composer 2.2+ 支持该命令;license 为空或 unknown 时需手动核查源码仓库 license 文件;json 输出可用 jq 或 grep 过滤,如 jq ‘map(select(.license | contains(“gpl”) or contains(“gpl”)))’。

Composer如何导出所有依赖包的许可证清单?(合规性检查)

composer show –licenses 只显示顶层包,怎么导出全部依赖的许可证?

它默认不递归composer show --licenses 只查 composer.json 里直接写的包,子依赖的许可证全被忽略。合规审计时这完全不够用。

  • 必须加 --recursive 参数才会展开整个依赖树
  • 加上 --format=json 更方便后续解析(比如转 CSV 或过滤 MIT/AGPL)
  • 注意:Composer 2.2+ 才支持 --recursive,旧版本会报错 Unrecognized option: --recursive

推荐命令:composer show --licenses --recursive --format=json > licenses.json

许可证字段为空或显示 unknown 怎么办?

很多包的 composer.json 没填 license 字段,或者填了但值不规范(比如 "license": "BSD-3-Clause" 是对的,"license": "BSD" 就常被识别为 unknown)。

  • 空 license 不代表无许可,只是元数据缺失;得手动查对应包的 LICENSE 文件或 github 主页
  • composer show 不读取实际 LICENSE 文件内容,只读 composer.jsonlicense 字段
  • 遇到 unknown,优先检查该包的源码仓库根目录,别信 Packagist 页面上“自动提取”的 license 标签

想按许可证类型筛选(比如只导出 GPL 相关包)

JSON 输出结构是扁平数组,每项含 nameversionlicense 字段,适合用 jq 过滤。

  • 查所有含 GPL 的:composer show --licenses --recursive --format=json | jq 'map(select(.license | contains("GPL") or contains("gpl")))'
  • 注意大小写:有些包写 "GPL-2.0-only",有些写 "gpl-3.0",建议用 ascii_downcase 统一处理
  • 如果没装 jq,临时用 grep -i gpl 也行,但会漏掉跨行或嵌套结构里的匹配

为什么 vendor/composer/installed.json 里 license 字段和 show 命令结果不一致?

因为 installed.json 存的是安装时抓取的原始元数据,而 composer show 会做归一化处理(比如把 MITmit"The MIT License" 都映射成 MIT)。

  • 合规审计应以 composer show --licenses --recursive 为准,它调用了 Composer 内部的 license 解析器
  • 直接读 installed.json 容易误判——例如 "license": ["proprietary"] 在 installed.json 里是数组,show 命令会转成字符串 proprietary
  • 另外,installed.json 不包含 require-dev 的包,而 --recursive 默认包含(除非加 --no-dev

真正麻烦的是那些没声明 license 却在运行时动态加载代码的包,比如某些 fork 后删了 LICENSE 文件的私有组件——这种只能靠人工核对,工具扫不出来。

text=ZqhQzanResources