composer licenses --format=json 并非唯一可脚本化的起点,因该命令根本不存在;实际唯一可靠命令是 composer show --format=json --no-dev,需配合 --locked 读取 composer.lock 并用 jq 安全解析 license 字段(支持字符串或数组),严格比对白名单,且必须人工核验模糊声明与 SPDX 一致性。

composer licenses --format=json 是唯一可脚本化的起点
Composer 自带的 composer licenses 命令默认输出无结构表格,列宽浮动、换行不可控,grep 或 awk 切分极易漏判(比如 MIT 被截成两行)。真正能进 CI 脚本的,只有 --format=json 输出——它从 Composer 2.2+ 开始稳定支持,每项含 name、license、dev 等明确字段,无需正则猜位置。
必须加 --locked:否则依赖解析走 composer.json,会漏掉传递依赖(如 symfony/polyfill-intl-idn);也必须加 --no-dev,否则开发工具类包(如 phpunit)的宽松许可证可能掩盖生产链风险。
示例命令:
composer licenses --format=json --locked --no-dev | jq -r '.[] | "\(.name)\t\(.license // ["unknown"] | join(" | "))"'
jq + 白名单配置是事实标准,不是可选项
别用 grep -E "(GPL|AGPL)" 这类暴力匹配——它会把 GPL-2.0-only 和 GPL-3.0-or-later 当作同一类处理,而合规要求恰恰取决于“only”还是“or-later”。正确做法是用 jq 遍历每个 license 字段(注意:它可能是字符串或数组),逐项比对分级白名单:
-
allowed列表:直接通过,如"MIT"、"Apache-2.0" -
review_required列表:命中即失败并输出提示,如"GPL-3.0-only"、"Unlicense" - 空值、
"proprietary"、"SEE LICENSE IN LICENSE.md":一律拒绝,不进任一列表
大小写必须统一处理:jq 'map(.license |= (if type == "array" then map(ascii_upcase) else ascii_upcase end))'
CI 中必须隔离 dev-dependencies 的许可证污染
composer licenses 默认包含 require-dev 包,但它们的许可证宽松不代表生产代码安全。问题在于:某些 dev 包(如 roave/security-advisories)会被误引入 autoload,或其代码片段意外打包进构建产物。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
两个可靠方案:
- 用
composer install --no-dev后再跑许可证检查(推荐,确保 vendor/ 状态与部署一致) - 用
jq 'map(select(.dev != true))'过滤 JSON 输出(适合只读composer.lock的轻量 CI 步骤)
切勿依赖删掉 require-dev 字段来“临时忽略”——这破坏契约,下次 composer update 可能拉错版本。
没有“自动过滤”的插件,只有硬拦截的脚本
不存在一个 Composer 插件能在 install 前拦住不合规 license。所谓“过滤”,本质是 CI 流程中插入的校验步骤:解析 composer.lock → 提取 license → 比对策略 → exit 1 中断构建。
常见错误:
- 用
composer show vendor/package:它依赖已安装的vendor/,CI 中install尚未执行,命令直接报错 - 信
license字段值为 URL(如"https://example.com/LICENSE"):jq会输出unknown,这类必须人工确认,不能跳过 - 把
--format=summary当合规依据:它只统计数量,不暴露具体哪个包违规
最易被忽略的一点:有些包 license 字段是 ["MIT", "Apache-2.0"],需判断是否至少一项在白名单内,而不是简单字符串包含匹配。

















