Repository navigation
fix(pre-commit): resolve prettier plugins from nearest package.json dir - #370
Merged
twistedmelonman merged 2 commits intoSep 25, 2026
Merged
Conversation
The prettier hook ran `npx prettier --write --ignore-unknown "$@"` from the repo root. Prettier resolves a .prettierrc's `plugins:` entries relative to the process cwd, not the config file, so any repo with per-package node_modules (no root install) failed to resolve a plugin declared by a nested package's .prettierrc, blocking every commit that touched it. Extract the entry into git/hooks/lint-prettier.sh, which walks up from each file to the nearest package.json and runs prettier from there, falling back to the previous behavior when no package.json ancestor exists. Rejects a resolved relative path that climbs out of the package dir, and makes each prettier invocation's exit code explicit as defensive clarity (set -e already propagates a failing subshell; this is not a fix for that). The `bash -c '$HOME/...' --` entry form matches the existing lint-shell, lint-yamllint, lint-markdown, and lint-zizmor entries at pre-commit/config.yaml lines 82/101/160/218. lint-prettier.sh is deployed to ~/.config/git/hooks by symlink repair (install.sh), which does not run itself on every machine (ASIAGO, TILSIT, MIMOLETTE). A machine that has pulled this change but not yet re-run install/repair would hit "No such file" on every prettier commit, so the entry now falls back to the pre-fix behavior (bare `npx prettier`) when the script is not yet present at that path. Closes #321
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
New VERDICT: PASS |
twistedmelonman
deleted the
claude/fix-prettier-nested-node-modules-8a854048
branch
September 25, 2026 20:53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #321. The
prettierpre-commit hook rannpx prettier --write --ignore-unknown "$@"from the repo root. Prettier resolves a.prettierrc'splugins:entries relative to the process cwd, not the config file that declares them, so any repo with per-packagenode_modules(no root install) failed to resolve a plugin declared by a nested package's.prettierrc, blocking every commit that touched it.Changes
git/hooks/lint-prettier.sh(new): walks each staged file up to its nearestpackage.jsonancestor and runsnpx prettierfrom there, so resolution finds that package's ownnode_modules. Falls back to the previous behavior (run from the given path) when nopackage.jsonancestor exists. Rejects a resolved relative path that climbs out of the package dir.pre-commit/config.yaml: prettier hook'sentrynow calls$HOME/.config/git/hooks/lint-prettier.sh, matching the existinglint-shell,lint-yamllint,lint-markdown, andlint-zizmorentries (lines 82/101/160/218). The entry falls back to the pre-fixnpx prettiercall when that script isn't present yet, sincelint-prettier.shis deployed to~/.config/git/hooksby symlink repair (install.sh), which doesn't run itself — a machine that has pulled this change but not yet re-run install/repair would otherwise hit "No such file" on every prettier commit.bash/tests/test-lint-prettier-nested-node-modules.sh(new): known-bad case reproduces the issue's exact repro shape (nested package, no rootpackage.json), then verifies the fixed script resolves the plugin, the no-package.jsonfallback still formats, no-files exits clean, and theconfig.yamlentry itself falls back to the oldnpx prettiercodepath (proven via a stubnpx) when the script isn't installed.Note on local review
The commit-time reviewer initially flagged the
$HOME/...entry form as a BLOCKING false positive ("$HOMEnot expanded"), on two separate commit attempts. This is disproven by:bash -c '$HOME/...' --form (lines 82/101/160/218, from PRs fix(zizmor): resolve config the way CI does instead of leaving it to discovery #344/feat(hooks): resolve yamllint config the way CI does #347/docs(hooks): cite run-standards.sh blocks by name, not by line number #349).bash -cexpands$HOMEat runtime when executing the single-quoted-cstring (verified against a nonexistent path — the error showed the fully-expanded path, not a literal$HOME).HOMEand confirms expansion works.On the third commit attempt the adversarial-reviewer returned PASS and correctly identified the code-reviewer's claim as false; the arbiter sided with it and the commit went through on its own merits, not via a bypass.
Test plan
bash bash/tests/run-tests.sh— 34/34 passedshellcheck -S infoclean, no disable directives