From 7cdf42d7707d54051645890c472d4916f05bbff5 Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Sat, 11 Jul 2026 11:54:42 -0700 Subject: [PATCH] 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 --- .github/workflows/test-litellm-ui-lint.yml | 2 +- scripts/pre_commit_lint.sh | 13 ++---- ui/litellm-dashboard/eslint-metrics.json | 8 ---- ui/litellm-dashboard/package.json | 1 - .../scripts/check-lint-budgets.mjs | 40 ++----------------- .../scripts/lint-budget-lib.mjs | 7 ---- .../scripts/update-lint-metrics.mjs | 25 ------------ .../tests/lint-budget-lib.test.ts | 20 +--------- 8 files changed, 8 insertions(+), 108 deletions(-) delete mode 100644 ui/litellm-dashboard/eslint-metrics.json delete mode 100644 ui/litellm-dashboard/scripts/update-lint-metrics.mjs diff --git a/.github/workflows/test-litellm-ui-lint.yml b/.github/workflows/test-litellm-ui-lint.yml index 226cbf6a879..5a5c4709ca2 100644 --- a/.github/workflows/test-litellm-ui-lint.yml +++ b/.github/workflows/test-litellm-ui-lint.yml @@ -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' }} diff --git a/scripts/pre_commit_lint.sh b/scripts/pre_commit_lint.sh index bd416ab814d..d6b79f0111a 100755 --- a/scripts/pre_commit_lint.sh +++ b/scripts/pre_commit_lint.sh @@ -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 ) } diff --git a/ui/litellm-dashboard/eslint-metrics.json b/ui/litellm-dashboard/eslint-metrics.json deleted file mode 100644 index 8ae7dc88c3d..00000000000 --- a/ui/litellm-dashboard/eslint-metrics.json +++ /dev/null @@ -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 -} diff --git a/ui/litellm-dashboard/package.json b/ui/litellm-dashboard/package.json index e35620c4996..40c495cebf1 100644 --- a/ui/litellm-dashboard/package.json +++ b/ui/litellm-dashboard/package.json @@ -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", diff --git a/ui/litellm-dashboard/scripts/check-lint-budgets.mjs b/ui/litellm-dashboard/scripts/check-lint-budgets.mjs index db0842fb2ec..3eec15a3a26 100644 --- a/ui/litellm-dashboard/scripts/check-lint-budgets.mjs +++ b/ui/litellm-dashboard/scripts/check-lint-budgets.mjs @@ -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); diff --git a/ui/litellm-dashboard/scripts/lint-budget-lib.mjs b/ui/litellm-dashboard/scripts/lint-budget-lib.mjs index a43305fc4ed..9b32bb0d3a0 100644 --- a/ui/litellm-dashboard/scripts/lint-budget-lib.mjs +++ b/ui/litellm-dashboard/scripts/lint-budget-lib.mjs @@ -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 })); -} diff --git a/ui/litellm-dashboard/scripts/update-lint-metrics.mjs b/ui/litellm-dashboard/scripts/update-lint-metrics.mjs deleted file mode 100644 index 16704d1f7a2..00000000000 --- a/ui/litellm-dashboard/scripts/update-lint-metrics.mjs +++ /dev/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); diff --git a/ui/litellm-dashboard/tests/lint-budget-lib.test.ts b/ui/litellm-dashboard/tests/lint-budget-lib.test.ts index 75b5efe6d1d..c66cdd1e2ab 100644 --- a/ui/litellm-dashboard/tests/lint-budget-lib.test.ts +++ b/ui/litellm-dashboard/tests/lint-budget-lib.test.ts @@ -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 }]); - }); -});