composer validate 默认不拦截非法提交,必须配合 --strict 和 --no-check-publish 选项、正确路径及可靠执行方式(如 php composer.phar)才能在 pre-push 钩子中真正生效并中断推送。

composer validate 能在 git push 前自动校验 composer.json 合法性,但默认不拦截非法提交——必须手动配置 pre-push 或 pre-commit 钩子并确保失败时退出码非零。
为什么 composer validate 在 Git Hook 里经常“没反应”
常见现象:钩子脚本里写了 composer validate,但改坏 composer.json(比如删掉逗号)后仍能 git push 成功。根本原因是:
-
composer validate默认只输出警告,不返回错误退出码(exit code != 0),Git Hook 无法感知失败 - 钩子运行路径可能不是项目根目录,
composer.json找不到 - 钩子用
sh执行但项目依赖bash特性(如[[ ]]),静默失败
必须加 --no-check-publish 和 --strict 才真正生效
composer validate 的默认行为太宽松:"name" 缺失只报 warning;schema 格式错也只 warn。要让 Git Hook 拦住问题,得强制它“严格模式”:
GInstall OneClick — 一键安装 GitHub 项目:规划、克隆、安装 Node 依赖、运行开发脚本。适用于想要获取 GitHubNode.js 项目的用户。
-
--strict:把所有 warning 升级为 error,触发非零退出码 -
--no-check-publish:跳过 Packagist 发布校验(否则会联网查包名是否已存在,拖慢钩子且无必要) - 组合命令必须是:
composer validate --strict --no-check-publish
pre-push 比 pre-commit 更适合审计 composer.json
选钩子类型不能只看“时机”,要看校验目标和执行成本:
-
pre-commit在每次git add后都跑,但composer.json不常改,频繁验证浪费时间 -
pre-push只在推送前执行一次,且天然覆盖所有待推分支的变更,更适合“入库前最终把关” - 注意:
pre-push钩子需放在.git/hooks/pre-push,不是.git/hooks/pre-commit - 示例脚本开头加
cd "$(git rev-parse --show-toplevel)"确保定位到项目根目录
钩子脚本里别直接写 composer,用 php composer.phar 更可靠
CI/CD 或某些本地环境可能没把 composer 加进 $PATH,或者版本不一致。安全做法是:
- 优先使用项目根目录下的
composer.phar(通过curl -sS https://getcomposer.org/installer | php安装) - 钩子中调用:
php composer.phar validate --strict --no-check-publish - 如果没
composer.phar,再 fallback 到全局composer,但必须显式检查是否存在:command -v composer >/dev/null 2>&1 || { echo "composer not found"; exit 1; }
真正的难点不在写命令,而在让钩子“稳定失败”——只要 composer.json 有 schema 错误、字段缺失或格式混乱,就必须中断推送。很多人卡在退出码没传上去,或者钩子路径错了却没报错信息,结果以为功能正常,其实形同虚设。










