mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
chore(ui): remove eslint-metrics.json lint-count snapshot
The eslint-metrics.json snapshot duplicated the violation counts already enforced by eslint-budgets.json. Keeping it current added a CI drift check, a pre-commit regenerate-and-flag step, and a standalone npm run lint:metrics script, none of which caught anything the budget gate did not, yet all of which failed noisily whenever the snapshot went stale. This drops the file and that machinery while leaving eslint-budgets.json as the actual ratchet gate
This commit is contained in:
parent
9659ae2f40
commit
7cdf42d770
8 changed files with 8 additions and 108 deletions
2
.github/workflows/test-litellm-ui-lint.yml
vendored
2
.github/workflows/test-litellm-ui-lint.yml
vendored
|
|
@ -85,7 +85,7 @@ jobs:
|
|||
if: ${{ !cancelled() && steps.changed.outputs.has_files == 'true' }}
|
||||
run: |
|
||||
npx eslint . -f json -o "$RUNNER_TEMP/lint-report.json" || true
|
||||
node scripts/check-lint-budgets.mjs "$RUNNER_TEMP/lint-report.json" eslint-budgets.json --check eslint-metrics.json
|
||||
node scripts/check-lint-budgets.mjs "$RUNNER_TEMP/lint-report.json" eslint-budgets.json
|
||||
|
||||
- name: Check for dead code (knip)
|
||||
if: ${{ !cancelled() && steps.changed.outputs.has_files == 'true' }}
|
||||
|
|
|
|||
|
|
@ -75,19 +75,12 @@ EOF
|
|||
npx eslint --no-warn-ignored --pass-on-unpruned-suppressions "${eslint_rel[@]}" || rc=1
|
||||
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. 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.
|
||||
# counts are not diff-scoped, so a local pass here means the budget step will
|
||||
# pass in CI too.
|
||||
report=$(mktemp)
|
||||
npx eslint . -f json -o "$report" || true
|
||||
node scripts/check-lint-budgets.mjs "$report" eslint-budgets.json --write eslint-metrics.json || rc=1
|
||||
node scripts/check-lint-budgets.mjs "$report" eslint-budgets.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
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"@typescript-eslint/no-explicit-any": 1971,
|
||||
"complexity": 129,
|
||||
"local/no-large-inline-object-arg": 501,
|
||||
"local/no-long-condition-chain": 234,
|
||||
"max-depth": 59,
|
||||
"no-console": 16
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@
|
|||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint .",
|
||||
"lint:metrics": "node scripts/update-lint-metrics.mjs",
|
||||
"test": "vitest",
|
||||
"test:dot": "vitest --reporter=dot",
|
||||
"test:watch": "vitest -w",
|
||||
|
|
|
|||
|
|
@ -1,20 +1,7 @@
|
|||
import { readFileSync, writeFileSync } from "fs";
|
||||
import { countBudgetViolations, findDrift } from "./lint-budget-lib.mjs";
|
||||
import { readFileSync } from "fs";
|
||||
import { countBudgetViolations } from "./lint-budget-lib.mjs";
|
||||
|
||||
const argv = process.argv.slice(2);
|
||||
const positional = [];
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
const [reportPath, budgetsPath] = positional;
|
||||
const [reportPath, budgetsPath] = process.argv.slice(2);
|
||||
const report = JSON.parse(readFileSync(reportPath, "utf8"));
|
||||
const budgets = JSON.parse(readFileSync(budgetsPath, "utf8"));
|
||||
const counts = countBudgetViolations(report, budgets);
|
||||
|
|
@ -32,25 +19,4 @@ 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);
|
||||
for (const { rule, committed: was, actual } of drift) {
|
||||
console.error(
|
||||
`::error::${flags.check} is stale for ${rule}: committed ${was ?? "missing"}, actual ${actual ?? "not a tracked rule"}.`,
|
||||
);
|
||||
}
|
||||
if (drift.length > 0) {
|
||||
console.error(`::error::Run \`npm run lint:metrics\` and commit ${flags.check}.`);
|
||||
failed = true;
|
||||
} else {
|
||||
console.log(`${flags.check} is up to date.`);
|
||||
}
|
||||
}
|
||||
|
||||
process.exit(failed ? 1 : 0);
|
||||
|
|
|
|||
|
|
@ -13,10 +13,3 @@ export function countBudgetViolations(report, budgets) {
|
|||
.map((rule) => [rule, counts[rule] || 0]),
|
||||
);
|
||||
}
|
||||
|
||||
export function findDrift(committed, actual) {
|
||||
const rules = [...new Set([...Object.keys(actual), ...Object.keys(committed)])].sort();
|
||||
return rules
|
||||
.filter((rule) => committed[rule] !== actual[rule])
|
||||
.map((rule) => ({ rule, committed: committed[rule] ?? null, actual: actual[rule] ?? null }));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
import { execSync } from "child_process";
|
||||
import { mkdtempSync, readFileSync, writeFileSync, rmSync } from "fs";
|
||||
import { tmpdir } from "os";
|
||||
import { join } from "path";
|
||||
import { countBudgetViolations } from "./lint-budget-lib.mjs";
|
||||
|
||||
const ESLINT_EXIT_LINT_ERRORS = 1;
|
||||
|
||||
const budgets = JSON.parse(readFileSync("eslint-budgets.json", "utf8"));
|
||||
const dir = mkdtempSync(join(tmpdir(), "litellm-lint-"));
|
||||
const reportPath = join(dir, "report.json");
|
||||
|
||||
try {
|
||||
execSync(`npx eslint . -f json -o "${reportPath}"`, { stdio: "inherit" });
|
||||
} catch (err) {
|
||||
if (err.status !== ESLINT_EXIT_LINT_ERRORS) throw err;
|
||||
}
|
||||
|
||||
const report = JSON.parse(readFileSync(reportPath, "utf8"));
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
|
||||
const metrics = countBudgetViolations(report, budgets);
|
||||
writeFileSync("eslint-metrics.json", JSON.stringify(metrics, null, 2) + "\n");
|
||||
console.log("Updated eslint-metrics.json");
|
||||
console.table(metrics);
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { describe, it, expect } from "vitest";
|
||||
import { countBudgetViolations, findDrift } from "../scripts/lint-budget-lib.mjs";
|
||||
import { countBudgetViolations } from "../scripts/lint-budget-lib.mjs";
|
||||
|
||||
const budgets = {
|
||||
"@typescript-eslint/no-explicit-any": { max: 10, target: 5 },
|
||||
|
|
@ -35,21 +35,3 @@ describe("countBudgetViolations", () => {
|
|||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findDrift", () => {
|
||||
it("reports no drift when the snapshot matches the actual counts", () => {
|
||||
expect(findDrift({ complexity: 5 }, { complexity: 5 })).toEqual([]);
|
||||
});
|
||||
|
||||
it("detects a changed count", () => {
|
||||
expect(findDrift({ complexity: 5 }, { complexity: 7 })).toEqual([{ rule: "complexity", committed: 5, actual: 7 }]);
|
||||
});
|
||||
|
||||
it("detects a rule missing from the committed snapshot", () => {
|
||||
expect(findDrift({}, { complexity: 7 })).toEqual([{ rule: "complexity", committed: null, actual: 7 }]);
|
||||
});
|
||||
|
||||
it("detects a phantom rule the committed snapshot still carries", () => {
|
||||
expect(findDrift({ "removed-rule": 3 }, {})).toEqual([{ rule: "removed-rule", committed: 3, actual: null }]);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue