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
2 changes: 1 addition & 1 deletion .github/workflows/test-litellm-ui-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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' }}
Expand Down
13 changes: 3 additions & 10 deletions scripts/pre_commit_lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
}
Expand Down
8 changes: 0 additions & 8 deletions ui/litellm-dashboard/eslint-metrics.json

This file was deleted.

1 change: 0 additions & 1 deletion ui/litellm-dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
40 changes: 3 additions & 37 deletions ui/litellm-dashboard/scripts/check-lint-budgets.mjs
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -23,7 +10,7 @@
for (const [rule, { max, target }] of Object.entries(budgets)) {
const count = counts[rule];
const note = count > max ? "OVER BUDGET" : count <= target ? "at target" : `${max - count} of headroom`;
console.log(`${rule}: ${count} | max: ${max} | target: ${target} | ${note}`);

Check warning on line 13 in ui/litellm-dashboard/scripts/check-lint-budgets.mjs

View workflow job for this annotation

GitHub Actions / frontend-lint

Unexpected console statement. Only these console methods are allowed: warn, error
if (count > max) {
console.error(
`::error::${rule} budget exceeded (${count} > ${max}). Reduce usage; lower max in eslint-budgets.json as the count drops.`,
Expand All @@ -32,25 +19,4 @@
}
}

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);
7 changes: 0 additions & 7 deletions ui/litellm-dashboard/scripts/lint-budget-lib.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }));
}
25 changes: 0 additions & 25 deletions ui/litellm-dashboard/scripts/update-lint-metrics.mjs

This file was deleted.

20 changes: 1 addition & 19 deletions ui/litellm-dashboard/tests/lint-budget-lib.test.ts
Original file line number Diff line number Diff line change
@@ -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 },
Expand Down Expand Up @@ -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