chore(tooling): drop scripts/lint-changed.sh — the shared gate runner's Stop hook lints the turn's files, shellcheck included

This commit is contained in:
2026-10-17 17:22:35 +02:00
parent 66181d1394
commit 460bdec406
2 changed files with 1 additions and 68 deletions
+1 -4
View File
@@ -46,12 +46,9 @@ bash scripts/check.sh lint # the static lanes only (no tests, build or audits)
bash scripts/check.sh --brief # either mode: one line per lane, output only for a red one
bash scripts/check.sh --list # the lane names, one per line (runs nothing)
bash scripts/check.sh --only "vitest" # one lane, by its exact name — never "the gate"
bash scripts/lint-changed.sh # ruff + eslint + prettier on the uncommitted files only
```
It runs every lane even after one fails and names each red one at the end. `lint-changed.sh` is a
convenience, not the gate; with `--hook` it doubles as a Claude Code Stop hook (silent when clean,
the findings handed back otherwise).
It runs every lane even after one fails and names each red one at the end.
The codebase's health numbers — size, complexity, test ratio, gate weight, comment noise — come from
`python scripts/audit_metrics.py` (seconds; it reports, it never fails). `--speed` adds the speed
-64
View File
@@ -1,64 +0,0 @@
#!/usr/bin/env bash
# The fast lint lanes on the uncommitted files only — ruff (check + format) on Python, eslint on the
# frontend's code and prettier on all of the frontend — for a check after every edit instead of a
# full gate run. It is a convenience, never the gate: scripts/check.sh stays what a merge or a
# release requires.
#
# bash scripts/lint-changed.sh lint what `git status` shows as changed or new
# bash scripts/lint-changed.sh --hook the same, as a Claude Code Stop hook: silent and exit 0 when
# clean; otherwise the findings on stderr and exit 2, which
# hands them back to the agent before it ends its turn
#
# Measured 2026-10-04: one cold eslint run (type-aware) takes 3.4–4.7 s, so this runs once per turn
# (Stop), not after every edit — a warm daemon (eslint_d) would add a dependency and a stray process.
set -u
cd "$(dirname "$0")/.." || exit 2
hook=0
[ "${1:-}" = --hook ] && hook=1
if [ "$hook" = 1 ]; then
# A Stop hook that blocked once is told so on the next stop; let that one through, or an unfixable
# finding would keep the agent in a loop.
grep -q '"stop_hook_active": *true' && exit 0
fi
mapfile -t changed < <(git status --porcelain --untracked-files=all | sed -E 's/^.. //; s/.* -> //' |
while read -r f; do [ -f "$f" ] && printf '%s\n' "$f"; done)
# eslint reads code; prettier reads every file the gate's `prettier --check .` does (a locale JSON,
# a stylesheet), and `--ignore-unknown` passes over the ones it has no parser for.
py=() fe=() pretty=()
for f in "${changed[@]}"; do
case "$f" in
backend/*.py | scripts/*.py) py+=("$f") ;;
esac
case "$f" in
frontend/*.ts | frontend/*.tsx | frontend/*.js | frontend/*.mjs) fe+=("${f#frontend/}") ;;
esac
case "$f" in
frontend/*) pretty+=("${f#frontend/}") ;;
esac
done
report="$(
if [ ${#py[@]} -gt 0 ]; then
python -m ruff check --quiet --config backend/ruff.toml "${py[@]}" 2>&1
python -m ruff format --check --quiet --config backend/ruff.toml "${py[@]}" 2>&1
fi
if [ ${#fe[@]} -gt 0 ]; then
(cd frontend && npx eslint --max-warnings 0 "${fe[@]}" 2>&1)
fi
if [ ${#pretty[@]} -gt 0 ]; then
(cd frontend && npx prettier --check --ignore-unknown --log-level warn "${pretty[@]}" 2>&1)
fi
)"
if [ -z "$report" ]; then
[ "$hook" = 1 ] || echo "lint-changed: clean (${#py[@]} py, ${#pretty[@]} frontend)"
exit 0
fi
if [ "$hook" = 1 ]; then
printf 'lint-changed found problems in the uncommitted files:\n%s\n' "$report" >&2
exit 2
fi
printf '%s\n' "$report"
exit 1