composer list 不能获取已安装包列表,它仅显示可用命令;正确命令是 composer show --installed --format=json,该命令输出稳定结构的json数据,可供jq可靠解析,包含name、version等字段,是机器可读的权威依赖源。

如何用 composer list 获取已安装包列表?
composer list 本身不输出包信息,它只是显示可用命令。真正要拿到依赖列表,得用 composer show 或更直接的 composer show --installed --no-ansi。这个命令输出的是人类可读格式(带缩进和空行),不适合直接喂给 jq —— 它需要 JSON。
所以第一步必须切换到 JSON 输出:
composer show --installed --format=json
这是唯一能被 jq 可靠解析的原始数据源。别试图对 composer list 的输出做字符串切分,那会因空格、换行、包名含连字符等立刻崩。
常见错误现象:用 composer list | jq 得到 parse error 或空结果——因为输入根本不是 JSON。
为什么必须加 --format=json 而不是用 jq 解析文本?
Composer 的文本输出没有固定列宽或分隔符:symfony/console 和 monolog/monolog 的版本号位置不一致;有些包有描述,有些没有;空行和缩进不可预测。任何基于 awk 或 sed 的解析在升级 Composer 后都可能失效。
而 --format=json 是 Composer 官方保证的机器可读接口,结构稳定:顶层是对象,packages 字段是数组,每个元素含 name、version、type 等键。
实操建议:
- 始终用
composer show --installed --format=json作为数据源头 - 避免管道里混用
grep或cut处理非结构化输出 - 若需过滤 dev-only 包,用
jq 'select(.packages[].type != "dev")',而不是靠包名关键词
用 jq 统计各包的版本分布(含预发布版识别)
目标是看清哪些包用了 dev-main、dev-develop、v2.3.0-rc1 这类非稳定版本。纯靠 version 字段字符串匹配容易漏判。
关键技巧:用 jq 的正则判断版本稳定性:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
jq '.packages[] | select(.version | test("^(dev-|v?[0-9]+\.[0-9]+\.[0-9]+(-[a-z0-9]+)?$)"))'—— 匹配语义化版本或 dev 分支 -
jq '.packages | group_by(.version) | map({version: .[0].version, count: length}) | sort_by(.count) | reverse'—— 按版本聚合计数 - 要单独列出所有非稳定版:
jq '.packages[] | select(.version | test("^(dev-|-[a-z]|-\d)")) | .name + " " + .version'
注意:jq 的 test() 默认区分大小写,dev-main 和 DEV-main 不会同时匹配——但 Composer 输出全是小写,无需额外处理。
统计结果容易被忽略的边界情况
实际跑出来的统计,常漏掉三类包:
-
root包(即当前项目自身)默认包含在--installed结果里,它的version是dev-main或1.0.0,但通常不该计入“第三方依赖”统计 —— 加select(.name != "<your-project-name>")</your-project-name>过滤 - 被
replace或provide替换的包不会出现在packages数组里,composer show只显示最终解析后的包,这点没问题;但若想看替换关系,得查composer.lock - 某些包的
version字段是9999999-dev(Composer 自动生成的“伪版本”),它既不是标准 semver,也不含dev-前缀,需单独用test("9999999-dev")捕获
dev-main 和 9999999-dev 并存很常见,只筛 dev- 会低估不稳定依赖数量。










