Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh
root=$(git rev-parse --show-toplevel 2>/dev/null) || exit 1
if [ ! -x "$root/node_modules/.bin/lint-staged" ]; then
echo "pre-commit: worktree preparation is incomplete (lint-staged is missing)" >&2
echo "pre-commit: run pnpm install before committing" >&2
exit 1
fi
# The binary directly, not `pnpm lint-staged`: pnpm runs a dependency-status
# check first and will try to purge node_modules when the lockfile moved, which
# aborts without a TTY — the commit then fails with a pnpm error that says
# nothing about linting. The guard above already established this path exists.
exec "$root/node_modules/.bin/lint-staged"
29 changes: 29 additions & 0 deletions lint-staged.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const dprint = "dprint fmt --config dprint.jsonc"

/**
* Staged files are linted as well as formatted, so a lint error is caught at the
* commit that introduced it rather than at the push gate or in CI.
*
* Lint and format share one array rather than two glob entries: lint-staged runs
* separate entries concurrently, and both of these rewrite the file. The globs
* below are disjoint for the same reason.
*
* `oxlint` here is the fast, non-type-aware pass — what can run per file in the
* time a commit should take. The full `--type-aware` lint and the format check
* still run in the ship gate and in CI, so this narrows the feedback loop rather
* than replacing them.
*
* `--no-error-on-unmatched-pattern` is required, not cosmetic: `.oxlintrc.json`
* ignores whole categories of file — `.js`, `.jsx`, `.d.ts` and `repos/**` among
* them — and without it oxlint exits non-zero on "No files found to lint", so
* staging only an ignored file would block the commit for no reason.
*
* @type {import('lint-staged').Configuration}
*/
export default {
"*.{ts,tsx,mts,cts}": [
"oxlint --quiet --fix --no-error-on-unmatched-pattern",
dprint
],
"*.{js,jsx,mjs,cjs,json,jsonc,md,toml,css,scss,sass,less,html,yml,yaml}": dprint
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"effect-app": "workspace:*",
"eslint": "^10.4.1",
"json5": "^2.2.3",
"lint-staged": "^17.3.0",
"madge": "^8.0.0",
"npm-check-updates": "^22.2.1",
"oxlint": "^1.67.0",
Expand Down
Loading
Loading