composer install 本身完全不检查 license 合规性,必须靠 ci 脚本解析 composer.lock 实现硬拦截;它只下载解压写入 vendor/,对 "license": "gpl-3.0" 或空值、url、"proprietary" 全部无视,法律风险由使用者承担。

Composer install 本身完全不检查 license 合规性,想在安装前拦截 GPL/AGPL/proprietary 等风险协议,必须靠 CI 脚本解析 composer.lock 实现硬拦截。
为什么 composer install 不拦 license 风险
Composer 只按依赖图下载、解压、写入 vendor/,对 "license": "GPL-3.0" 或空值、URL、"proprietary" 全部无视。哪怕你项目是闭源商业产品,它照样装成功——法律风险由你承担。composer install --dry-run 也不读 license 字段;composer audit 只查 CVE,跟协议类型无关;composer show 是装完才查,且只查显式 require 的包,传递依赖(如 symfony/polyfill-intl-idn)根本不会出现。
CI 中用 jq 提取并匹配 license 黑名单
关键前提是:不依赖 vendor/,直接读 composer.lock。推荐 Linux/macOS CI 脚本:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 用
jq -r '.packages[] | "\(.name)\t\(.version)\t\(.license // ["unknown"] | join(" | "))"' composer.lock输出所有包的 name/version/license - 对结果逐行
grep -E "(GPL|AGPL|LGPL|proprietary|unlicensed|unknown)" - 匹配到就
exit 1,阻断后续composer install - 注意:
license字段为空或为 URL(如"https://example.com/LICENSE")时,jq输出unknown,这类必须人工确认,不能跳过
composer show 和插件都不能替代人工核对
zicht/composer-license-plugin 会尝试读 LICENSE 文件,但无法处理 "SEE LICENSE IN LICENSE.md" 这类声明,更无法判断实际分发内容是否含 GPL 代码;composer show vendor/package 只返回作者写的字段值,不打开文件、不解释多协议含义(如 ["MIT", "Apache-2.0"] 是“二选一”还是“同时满足”),也不能告诉你该包是否在运行时动态加载了 GPL 模块。最终,LICENSE 文件全文仍需人工审阅——尤其是那些 license 字段为 unknown 或指向外部 URL 的包。
真正容易被忽略的是:协议合规不是一次扫描就能闭环的事。同一个包不同版本可能换协议(比如从 MIT 改成 MPL),而 composer.lock 锁的是具体 commit hash 或 dist zip,必须确保每次更新都重新过一遍 license 检查流程,否则旧版 lock 文件里的风险包会一直潜伏下去。










