Composer 没有原生 licenses 命令,composer show --licenses 仅提取 composer.json 中的 license 字段元数据,不校验法律效力、不读取 LICENSE 文件,遇 "SEE LICENSE IN X" 等需人工审计。

Composer 没有自动检测许可证合规性的能力——所谓“自动检测”全是误解或第三方工具包装的结果。真正能跑出来的只有 composer show --licenses,它只读元数据,不校验法律效力,也不打开 LICENSE 文件。
为什么 composer licenses 命令会报错
执行 composer licenses 时看到 Command "licenses" is not defined,不是你装错了,是 Composer 官方根本没实现这个命令。截至 2026 年 11 月,所有文档里写的这个命令,要么指向已废弃插件(如 zicht/composer-license-plugin),要么把第三方 CLI 工具(如 licensecheck 或 aquasecurity/trivy)冒充成 Composer 原生功能。
- Composer 核心命令列表里没有
licenses,连实验性标记都没有 - 试图用
composer global require装插件来“补上”,大概率在 Composer 2.5+ 上直接失败——插件机制已被大幅限制 - CI 流水线里写
composer licenses,等于埋了个必炸的定时炸弹
composer show --licenses 能做什么、不能做什么
这是目前唯一稳定、无需插件、全版本兼容的许可证元数据提取方式,但它只做一件事:从 vendor/ 下每个包的 composer.json 里原样取出 license 字段值。
- 必须先运行过
composer install或composer update,否则vendor/为空,命令直接报错No packages found - 加
--no-dev才能排除require-dev里的测试依赖(比如phpunit/phpunit的 MIT 不代表你生产环境用了 MIT) -
--format=json输出是扁平数组,解析时别用.packages这种路径,直接遍历.[].name和.[].license - 字段值可能是
"MIT"、["GPL-2.0-or-later", "Apache-2.0"]或"SEE LICENSE IN LICENSE.md"——它不展开、不归一化、不校验文件是否存在
哪些 license 字段值必须人工点开 LICENSE 文件核对
只要 composer show --licenses 输出里出现以下任意一种,自动化就该立刻停手,切换人工审计:
-
"SEE LICENSE IN LICENSE.md"或类似路径引用:Composer 绝不会去读那个文件,你得手动cat vendor/foo/bar/LICENSE.md -
"unlicensed"、"proprietary"、空字符串:法律盲区,不能靠“作者应该填对了”蒙混过关 -
"MIT"但项目根目录没标准 MIT 文本(比如缺版权年份、缺“permission notice”段落):SPDX 工具会标红,不算合规 -
["MIT", "GPL-3.0-only"]这类多许可:你实际集成方式决定适用哪条——动态链接?静态打包?SaaS 分发?每种场景法律结论不同
真正在 CI 里落地的最小可行方案
想让许可证检查进流水线,得组合三步:元数据提取 + 文件存在性检查 + 关键词扫描。不能只靠 Composer。
- 先用
composer show --licenses --no-dev --format=json > licenses.json导出元数据 - 用脚本遍历
licenses.json,对每个"SEE LICENSE IN X"执行test -f vendor/$pkg/X,缺失就 fail - 对所有非空 license 字段,用
grep -qE '^(MIT|Apache-2.0|BSD-3-Clause)$' 做白名单匹配;匹配不上就触发人工 review - 跳过
composer validate——它对 license 字段完全不校验,--strict也无效
复杂点在于:LICENSE 文件内容是否被修改过、是否含额外条款、是否和 SPDX 标准文本一致——这些都得靠人工比对,工具只能帮你定位到哪一行该看了。











