chore(git): add husky pre-push format hook#59
Conversation
- add husky devDependency and prepare script - configure pre-push hook to run pnpm format - harden sync-grammars and extend search hints test timeout to avoid flakiness
Greptile SummaryThis PR wires up Husky v9 to enforce code quality gates: Key changes:
Confidence Score: 3/5
|
| Filename | Overview |
|---|---|
| .husky/pre-push | New pre-push hook that runs pnpm format --write; this modifies files in the working tree after commits are finalized, so the pushed commits remain unformatted — the hook does not achieve its stated goal. |
| .husky/pre-commit | New pre-commit hook running pnpm test; missing a shebang line, inconsistent with the pre-push hook style. |
| package.json | Adds husky as a devDependency and a prepare script to install hooks on pnpm install; straightforward and correct. |
| scripts/sync-grammars.mjs | Adds EPERM/EBUSY error handling for Windows file locks; logic is sound but the copied counter is incremented even when a file is skipped, making the final log line misleading. |
| tests/search-hints.test.ts | Adds a 60-second timeout to the first integration test to reduce flakiness on slower machines; no functional changes. |
| pnpm-lock.yaml | Lockfile updated to add husky@9.1.7; auto-generated and consistent with package.json changes. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[git commit] --> B[pre-commit hook\npnpm test]
B -->|tests pass| C[Commit created]
B -->|tests fail| D[Commit blocked]
E[git push] --> F[pre-push hook\npnpm format --write]
F --> G{Files modified\nby formatter?}
G -->|Yes| H[Working tree modified\nbut NOT committed]
G -->|No| I[Push proceeds\nwith original commits]
H --> I
I --> J[Remote receives\noriginal unformatted commits]
H --> K[Developer left with\nunstaged formatted changes]
style H fill:#ffcccc,stroke:#cc0000
style J fill:#ffcccc,stroke:#cc0000
style K fill:#fff3cd,stroke:#ffa500
Last reviewed commit: b9381d7
.husky/pre-push
Outdated
| . "$(dirname -- "$0")/_/husky.sh" | ||
|
|
||
| echo "Running pnpm format before push..." | ||
| pnpm format |
There was a problem hiding this comment.
pnpm format modifies files but won't affect pushed commits
Running pnpm format (which uses --write) in a pre-push hook formats files in the working tree after the commits have already been made. The push then proceeds with the original, potentially unformatted commits — so the remote branch ends up with unformatted code. Additionally, the developer is left with uncommitted formatting changes in their working directory after every push, which is confusing.
To actually enforce formatting on pushed code, consider one of these alternatives:
- Fail fast with
format:check— reject the push if any file is unformatted, prompting the developer to format-and-commit before pushing:
| pnpm format | |
| pnpm format:check |
- Move formatting to the pre-commit hook — format files before staging so the commit itself contains formatted code (common pattern with lint-staged).
scripts/sync-grammars.mjs
Outdated
| throw error; | ||
| } | ||
| } | ||
| copied++; |
There was a problem hiding this comment.
copied counter inflated when file is skipped
When renameSync throws EPERM/EBUSY, the file is intentionally skipped (the tmp file is cleaned up and execution continues). However, copied++ is still incremented on line 64, so the final log line — "sync-grammars: X wasm files → destDir" — counts skipped files as if they were successfully updated. This makes it harder to tell at a glance that some grammars were left at their previous version.
Consider tracking skipped files separately:
try {
fs.renameSync(tmp, dest);
copied++;
} catch (error) {
...
if (...lock error...) {
skipped++;
console.warn(...);
} else {
throw error;
}
}
And update the final log to reflect both counts when skipped > 0.
.husky/pre-commit
Outdated
| @@ -0,0 +1 @@ | |||
| pnpm test | |||
There was a problem hiding this comment.
Missing shebang (inconsistent with pre-push)
The pre-push hook declares #!/usr/bin/env sh on its first line, but pre-commit doesn't. Without a shebang the kernel picks a default interpreter, which varies by OS/distro. It's safer and more explicit to be consistent:
| pnpm test | |
| #!/usr/bin/env sh | |
| pnpm test |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b9381d7215
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
.husky/pre-push
Outdated
| . "$(dirname -- "$0")/_/husky.sh" | ||
|
|
||
| echo "Running pnpm format before push..." | ||
| pnpm format |
There was a problem hiding this comment.
Fail pre-push when formatting changes are required
Running pnpm format here rewrites files but still exits successfully, so a push can proceed even when the commit being pushed is unformatted (the formatting only affects the local working tree after the fact). In the common case where formatting issues exist in staged commits, this hook gives a false pass and does not enforce formatting on remote history.
Useful? React with 👍 / 👎.
| // Best-effort cleanup; ignore if removal fails | ||
| } | ||
|
|
||
| if (error && typeof error === 'object' && 'code' in error && (error.code === 'EPERM' || error.code === 'EBUSY')) { |
There was a problem hiding this comment.
Treat EPERM as sync failure instead of lock warning
This branch suppresses all EPERM rename failures as if they were transient file locks, but EPERM also occurs for real permission/configuration problems (for example read-only worktrees or ACL restrictions). In those environments the script now reports success and continues with stale grammar binaries, masking a hard failure in prebuild/pretest flows.
Useful? React with 👍 / 👎.
- switch the pre-push hook to pnpm format:check so pushes fail before unformatted commits are sent - remove deprecated husky bootstrap lines from the hook file for v9-style hooks - report skipped grammar sync files separately from successful updates
|
Addressed the valid review points in �6d95fc:
Re-ran pnpm test and pnpm run format:check locally before pushing. |
Keep commits lightweight while enforcing formatting and tests before code is pushed.
Summary
Test plan