build(pre-commit): regenerate eslint-metrics.json instead of failing on drift (#32717)

The dashboard lint-budgets step ran check-lint-budgets.mjs in --check mode,
which fails and tells you to run `npm run lint:metrics` and re-stage by hand.
Add a --write mode that rewrites eslint-metrics.json from the same eslint
report, and have pre-commit use it, then flag drift via git diff so you
re-stage; this mirrors how the block below regenerates schema.d.ts. CI keeps
using --check, so it still fails on a stale committed metrics file.
This commit is contained in:
ryan-crabbe-berri 2026-07-10 11:51:58 -07:00 • committed by GitHub
parent e2eee36438
commit 270406b8ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 18 additions and 4 deletions

View file

@ -76,11 +76,18 @@ EOF
fi
# Whole-folder lint budgets, exactly as the frontend-lint job runs them: the
# counts and the committed metrics file are not diff-scoped, so a local pass
# here means the budget step will pass in CI too.
# here means the budget step will pass in CI too. Unlike CI (which --checks and
# fails), regenerate eslint-metrics.json from the same report — same as the
# gen:api block below regenerates schema.d.ts — then flag drift so you re-stage
# it, instead of making you run npm run lint:metrics by hand.
report=$(mktemp)
npx eslint . -f json -o "$report" || true
node scripts/check-lint-budgets.mjs "$report" eslint-budgets.json --check eslint-metrics.json || rc=1
node scripts/check-lint-budgets.mjs "$report" eslint-budgets.json --write eslint-metrics.json || rc=1
rm -f "$report"
if ! git diff --quiet -- eslint-metrics.json; then
echo "✗ eslint-metrics.json was stale; regenerated it. Stage it and re-run make pre-commit." >&2
rc=1
fi
exit $rc
)
}

View file

@ -4,5 +4,5 @@
"local/no-large-inline-object-arg": 512,
"local/no-long-condition-chain": 233,
"max-depth": 59,
"no-console": 15
"no-console": 16
}

View file

@ -1,4 +1,4 @@
import { readFileSync } from "fs";
import { readFileSync, writeFileSync } from "fs";
import { countBudgetViolations, findDrift } from "./lint-budget-lib.mjs";
const argv = process.argv.slice(2);
@ -7,6 +7,8 @@ const flags = {};
for (let i = 0; i < argv.length; i += 1) {
if (argv[i] === "--check") {
flags.check = argv[(i += 1)];
} else if (argv[i] === "--write") {
flags.write = argv[(i += 1)];
} else {
positional.push(argv[i]);
}
@ -30,6 +32,11 @@ for (const [rule, { max, target }] of Object.entries(budgets)) {
}
}
if (flags.write) {
writeFileSync(flags.write, JSON.stringify(counts, null, 2) + "\n");
console.log(`Wrote ${flags.write}.`);
}
if (flags.check) {
const committed = JSON.parse(readFileSync(flags.check, "utf8"));
const drift = findDrift(committed, counts);