mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 11:06:16 -08:00
* fix(lint): resolve module-boundary and prefer-inject errors Retag workspace-shell-util as type:data-access to match its injectable services that depend on @iptvnator/services, and convert RemoteControlService to inject(HttpClient). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(lint): enforce max-lines 400 with generated baseline Add a max-lines ESLint error (hard cap 400 raw lines per TypeScript file) per the repo file-size rule. The 134 pre-existing offenders are baselined in tools/eslint/max-lines-baseline.mjs, regenerable via generate-max-lines-baseline.mjs; the list should only shrink. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(ci): enforce lint on PRs and guard coverage policy drift - Add a Lint job to ci.yml running nx run-many -t lint --all, so module-boundary tags, legacy-alias bans, and max-lines gate merges. - Fix the root lint script (was linting only electron-backend). - Add tools/coverage/check-coverage-policy.mjs: fails CI when a project with a test target is missing from coverage-policy.json; wired into coverage:ci as coverage:policy:check. - Run Tier B/C unit tests in CI without coverage (list derived from the policy), so website/packaging/remote-control tests run on PRs. - Replace the hand-picked 16-project test:unit:ci list with --all. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: document CI lint enforcement and coverage policy guard Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ci): address bot review feedback on policy guard and baseline generator - Drive Tier B/C validation from each policy entry's validationCommand (falling back to nx test), skipping projects with an e2e target since the E2E workflow already runs them (Codex). - Fail when a Tier A entry has no test target (Greptile, adapted: checking all entries against test targets would false-positive on the intentionally spec-less e2e/mock-server tiers). - Guard against missing JSON array in nx show projects output (Greptile). - Scan .tsx files in the max-lines baseline generator to match the ESLint rule's file patterns (Greptile). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
69 lines
2.3 KiB
JavaScript
69 lines
2.3 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Regenerates tools/eslint/max-lines-baseline.mjs: the list of TypeScript
|
|
* files that already exceed the max-lines limit enforced in eslint.config.mjs.
|
|
* Baselined files are exempt from the rule; the list should only shrink.
|
|
*
|
|
* Usage: node tools/eslint/generate-max-lines-baseline.mjs
|
|
*/
|
|
|
|
import { readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
import path from 'node:path';
|
|
import process from 'node:process';
|
|
|
|
export const MAX_LINES = 400;
|
|
|
|
const workspaceRoot = process.cwd();
|
|
const scanRoots = ['apps', 'libs', 'tools'];
|
|
const skipDirs = new Set(['node_modules', 'dist', '.nx', 'coverage']);
|
|
|
|
function collectTsFiles(dir, results) {
|
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
if (entry.isDirectory()) {
|
|
if (!skipDirs.has(entry.name)) {
|
|
collectTsFiles(path.join(dir, entry.name), results);
|
|
}
|
|
} else if (
|
|
(entry.name.endsWith('.ts') || entry.name.endsWith('.tsx')) &&
|
|
!entry.name.endsWith('.d.ts')
|
|
) {
|
|
results.push(path.join(dir, entry.name));
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
function countLines(filePath) {
|
|
const content = readFileSync(filePath, 'utf8');
|
|
if (content.length === 0) {
|
|
return 0;
|
|
}
|
|
const lines = content.split('\n').length;
|
|
return content.endsWith('\n') ? lines - 1 : lines;
|
|
}
|
|
|
|
const offenders = scanRoots
|
|
.flatMap((root) => collectTsFiles(path.join(workspaceRoot, root), []))
|
|
.map((filePath) => ({
|
|
file: path.relative(workspaceRoot, filePath).split(path.sep).join('/'),
|
|
lines: countLines(filePath),
|
|
}))
|
|
.filter(({ lines }) => lines > MAX_LINES)
|
|
.sort((a, b) => a.file.localeCompare(b.file));
|
|
|
|
const banner = `// Generated by tools/eslint/generate-max-lines-baseline.mjs — do not edit by hand.
|
|
// TypeScript files that predate the max-lines (${MAX_LINES}) ESLint rule.
|
|
// This list should only shrink: split a file below the limit, rerun the
|
|
// generator, and commit the result. Never add new files here.
|
|
`;
|
|
|
|
const body = offenders.map(({ file }) => ` '${file}',`).join('\n');
|
|
|
|
writeFileSync(
|
|
path.join(workspaceRoot, 'tools/eslint/max-lines-baseline.mjs'),
|
|
`${banner}export const maxLinesBaseline = [\n${body}\n];\n`
|
|
);
|
|
|
|
console.log(`Baselined ${offenders.length} files over ${MAX_LINES} lines.`);
|