Repository navigation
fix(uncheck): write the pre-commit hook husky 9 and Vite+ actually run - #9
Conversation
commit: |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
prepare.tspicks the file the dispatcher actually runs (prepare.ts:112-141) — when the configured hooks folder contains thehdispatcher,pre-commitis written one level up (.husky//.vite-hooks/) instead of the generated_/shim that the dispatcher exits past. Covers husky 9 and Vite+, while default.git/hooksand hand-setcore.hooksPathbehave as before.- No
chmodwhen dispatched — both dispatchers execute the project hook withsh -e, so the executable bit is unnecessary and preserving a committed hook's mode avoids a spuriousgit statusentry. The default/hand-set paths still get0o755. - Regression tests (
command.test.ts:1418-1556) — realgit commits through a faithful husky dispatcher from the root and a nested package, failing line blocks the commit, shim untouched, non-executable hook, Vite+ creates the parent-folder hook, and hand-setcore.hooksPath=.githooksstays executable and in place. - README (
README.md:135) documents the husky 9 / Vite+ behavior.
I verified the load-bearing external assumptions against vendor source rather than the repo's stand-ins. Husky v9.1.7 h computes s=$(dirname "$(dirname "$0")")/$n and runs sh -e "$s"; Vite+ packages/cli/src/config/hooks.ts installs _/h (mode 0o755), dispatches with "$__vp_shell" -e "$s", and itself treats _/h as the dispatcher marker. The h-existence heuristic therefore matches both tools' own contracts, and skipping chmod is correct for both. I also confirmed git rev-parse --git-path hooks returns a cwd-relative ../../.husky/_ from a nested package, so the existing path.resolve(cwd, hooks) resolution already lands correctly — the nested-package test exercises this. The new tests pass on head and, after reverting prepare.ts to the pre-fix commit, fail by writing .husky/_/pre-commit, so they are genuine regression coverage. The full uncheck prepare block passes (8/8), and oxfmt --check / oxlint are clean on both changed TS files.
One non-blocking observation, not a required change: if uncheck's prepare runs before the tool has generated _/h (e.g. a fresh clone with scripts ordered the other way), it will append to the shim for that run; once h exists the next install moves the line to the right folder, so the documented prepare: "husky && uncheck prepare --pre-commit" ordering keeps this from happening. No action needed.
DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏

With husky 9 or Vite+ (
vp config) managing git hooks,uncheck prepare --pre-commitnow writes to.husky/pre-commitor.vite-hooks/pre-commit, the file their dispatcher runs. Before, it appended to the generated shim in.husky/_or.vite-hooks/_and reported the hook as written, but the line never ran: the dispatcherhthe shim sources always exits first, and the nexthuskyorvp configrun wiped the line anyway. In those repos, commits were never checked.Fixes
hdispatcher, the hook goes into the folder above it, next to the user's own commands. Lines added by hand stay, monorepo packages each keep their own line, and rerunningpreparestays idempotent..husky/pre-commitkeeps its file mode, so installs no longer leave a mode change ingit status. The dispatcher runs the file withsh -e, so it doesn't need to be executable.core.hooksPathset by hand, such as.githooks, and the default.git/hookswork as before, including the executable bit.Testing
core.hooksPath=.husky/_with a stand-in dispatcher based on husky 9 and prepares from the root and from a nested package. Realgit commits run every line through the dispatcher, and a failing line blocks the commit. The shim is left untouched. This test fails on the previous version..vite-hooks/pre-commitgets the#!/bin/shheader, and that an existing hook only gets the line appended.core.hooksPathstill gets the hook, executable, in the folder as configured.preparenow describes the husky 9 and Vite+ behavior.