唯一可落地的结构化输入源是 composer licenses --format=json,因其输出为扁平数组且字段稳定,而默认纯文本表格因列宽动态、空格不固定、许可证名可能折行导致 grep/awk 解析必然失败。

composer licenses --format=json 是唯一可落地的结构化输入源
直接解析 composer licenses 默认的纯文本表格必然失败——列宽动态、空格不固定、许可证名可能折行(比如 BSD-3-Clause 在 80 列终端里被切成两行),grep 或 awk 硬切会漏判或误判。真正能进 CI 流水线的只有 JSON 输出,前提是 Composer ≥ 2.2。
- 执行
composer licenses --format=json > licenses.json,输出是扁平数组,每个元素含name、version、license、homepage等稳定字段,无格式干扰 -
license字段可能是字符串("MIT")、数组(["MIT", "Apache-2.0"])或 URL("https://example.com/LICENSE"),后两者需单独处理 - 旧版 Composer 不支持该参数,报错
Command "licenses" is not defined,必须先用composer --version校验,CI 中需显式指定版本(如 GitHub Actions 的composer-version: '2.5')
白名单必须分层:allowed / review_required / reject
把白名单写成一维数组是典型误区。合规不是二值判断,而是语义分级:有些许可证可直过,有些必须人工介入,有些则应直接阻断构建。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
allowed列表只放无条件接受的宽松许可,如MIT、Apache-2.0、BSD-3-Clause;大小写必须统一转大写再比对,避免mit或Mit匹配失败 -
review_required放强 copyleft 或法律效力存疑的许可,如GPL-2.0-only、AGPL-3.0-only、Unlicense;命中即记录并退出非零码,触发人工流程 -
reject显式列出非法值:proprietary、空字符串、unknown、SEE LICENSE IN LICENSE.md—— 这些不进白名单也不进复核,直接拒绝
dev-dependencies 必须显式剥离,否则许可证统计失真
composer licenses 默认包含 require-dev 包,但 PHPUnit、PHPStan 这类工具链依赖的 MIT 许可证,和你打包进生产镜像的代码毫无关系。混在一起统计,会掩盖真实风险。
- CI 中第一件事是运行
composer install --no-dev,再执行许可证检查,确保vendor/里只有 runtime 依赖 - 若需保留 dev 包做审计(如确认测试框架是否引入 GPL 代码),则用
jq过滤:jq 'map(select(.dev != true))' licenses.json - 注意
composer.lock里packages和packages-dev是分开字段,解析时别漏掉后者——它才是 dev 包的真实来源
license 字段 ≠ 法律依据,LICENSE 文件才作数
所有自动化检查都基于 composer.json 里的 license 字段,但它只是作者填写的字符串,Composer 不校验、不下载、不比对实际文件。真正具备法律效力的是包根目录下的 LICENSE 或 LICENSE.md 全文。
- 遇到
license值为 URL(如"https://raw.githubusercontent.com/xxx/LICENSE")或模糊描述(如"The MIT License"),脚本应标记为needs_manual_check并跳过自动比对 - 企业级扫描应调用
zicht/composer-license-plugin,它会尝试下载并解析实际 LICENSE 文件,把"The MIT License"归一化为MIT,但需注意私有仓库权限配置 - SPDX 标识符必须严格匹配官方列表(如
BSD-2-Clause不可简写为BSD),composer validate在 v2.5+ 会直接报错,Packagist 页面显示 ❓ 也是同一原因
license 字段的语义歧义和实际 LICENSE 文件的不可控性——自动化只能筛出明确违规项,模糊值和 URL 类型永远需要人工兜底。

















