fix: use import type for GraphConfig, remove verbatim-module-syntax exclusion
The verbatim-module-syntax lint rule was correctly flagging that GraphConfig is only used in a type position (typeof GraphConfig). Since typeof resolves purely at the type level, import type works fine here and is the correct form. No lint exclusion needed. Also: deno fmt across all files (markdown line wrapping).
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
import { parse } from "@std/flags";
|
||||
import * as path from "@std/path";
|
||||
|
||||
@@ -37,31 +36,31 @@ interface Stats {
|
||||
|
||||
function filterDiagnostics(
|
||||
diagnostics: LintDiagnostic[],
|
||||
options: FilterOptions
|
||||
options: FilterOptions,
|
||||
): LintDiagnostic[] {
|
||||
let result = diagnostics;
|
||||
|
||||
|
||||
if (options.codes) {
|
||||
const codes = new Set(options.codes);
|
||||
result = result.filter(d => codes.has(d.code));
|
||||
result = result.filter((d) => codes.has(d.code));
|
||||
}
|
||||
|
||||
|
||||
if (options.files) {
|
||||
const filePatterns = options.files.map(f => new RegExp(f));
|
||||
result = result.filter(d =>
|
||||
filePatterns.some(pattern => pattern.test(d.filename))
|
||||
const filePatterns = options.files.map((f) => new RegExp(f));
|
||||
result = result.filter((d) =>
|
||||
filePatterns.some((pattern) => pattern.test(d.filename))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function groupDiagnostics(
|
||||
diagnostics: LintDiagnostic[],
|
||||
groupBy: "code" | "file"
|
||||
groupBy: "code" | "file",
|
||||
): Record<string, LintDiagnostic[]> {
|
||||
const groups: Record<string, LintDiagnostic[]> = {};
|
||||
|
||||
|
||||
for (const diag of diagnostics) {
|
||||
const key = groupBy === "code" ? diag.code : diag.filename;
|
||||
if (!groups[key]) {
|
||||
@@ -69,24 +68,24 @@ function groupDiagnostics(
|
||||
}
|
||||
groups[key].push(diag);
|
||||
}
|
||||
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
function calculateStats(diagnostics: LintDiagnostic[]): Stats {
|
||||
const byCode: Record<string, number> = {};
|
||||
const byFile: Record<string, number> = {};
|
||||
|
||||
|
||||
for (const diag of diagnostics) {
|
||||
byCode[diag.code] = (byCode[diag.code] || 0) + 1;
|
||||
byFile[diag.filename] = (byFile[diag.filename] || 0) + 1;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
total: diagnostics.length,
|
||||
byCode,
|
||||
byFile,
|
||||
filesWithIssues: Object.keys(byFile).length
|
||||
filesWithIssues: Object.keys(byFile).length,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -94,14 +93,14 @@ function printStats(stats: Stats, topN: number = 10) {
|
||||
console.log("\n=== LINT ISSUE STATISTICS ===");
|
||||
console.log(`Total issues: ${stats.total}`);
|
||||
console.log(`Files with issues: ${stats.filesWithIssues}`);
|
||||
|
||||
|
||||
console.log(`\nTop ${topN} issue types:`);
|
||||
const sortedByCode = Object.entries(stats.byCode).sort((a, b) => b[1] - a[1]);
|
||||
for (let i = 0; i < Math.min(topN, sortedByCode.length); i++) {
|
||||
const [code, count] = sortedByCode[i];
|
||||
console.log(` ${code}: ${count}`);
|
||||
}
|
||||
|
||||
|
||||
console.log(`\nTop ${topN} files with most issues:`);
|
||||
const sortedByFile = Object.entries(stats.byFile).sort((a, b) => b[1] - a[1]);
|
||||
for (let i = 0; i < Math.min(topN, sortedByFile.length); i++) {
|
||||
@@ -113,29 +112,33 @@ function printStats(stats: Stats, topN: number = 10) {
|
||||
function printGroupedDiagnostics(
|
||||
groups: Record<string, LintDiagnostic[]>,
|
||||
groupBy: "code" | "file",
|
||||
limit?: number
|
||||
limit?: number,
|
||||
) {
|
||||
const sortedEntries = Object.entries(groups).sort(
|
||||
(a, b) => b[1].length - a[1].length
|
||||
(a, b) => b[1].length - a[1].length,
|
||||
);
|
||||
|
||||
|
||||
const entriesToShow = limit ? sortedEntries.slice(0, limit) : sortedEntries;
|
||||
|
||||
|
||||
for (const [key, diagnostics] of entriesToShow) {
|
||||
console.log(`\n${groupBy.toUpperCase()}: ${key} (${diagnostics.length} issues)`);
|
||||
console.log(
|
||||
`\n${groupBy.toUpperCase()}: ${key} (${diagnostics.length} issues)`,
|
||||
);
|
||||
// Show first 5 issues for each group to avoid overwhelming output
|
||||
const issuesToShow = Math.min(5, diagnostics.length);
|
||||
for (let i = 0; i < issuesToShow; i++) {
|
||||
const diag = diagnostics[i];
|
||||
console.log(
|
||||
` ${path.basename(diag.filename)}:${diag.range.start.line + 1}:${diag.range.start.col + 1} - ${diag.message}`
|
||||
` ${path.basename(diag.filename)}:${diag.range.start.line + 1}:${
|
||||
diag.range.start.col + 1
|
||||
} - ${diag.message}`,
|
||||
);
|
||||
}
|
||||
if (diagnostics.length > issuesToShow) {
|
||||
console.log(` ... and ${diagnostics.length - issuesToShow} more issues`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (limit && sortedEntries.length > limit) {
|
||||
console.log(`\n... and ${sortedEntries.length - limit} more groups`);
|
||||
}
|
||||
@@ -147,14 +150,14 @@ async function runDenoLint(): Promise<LintResult> {
|
||||
stdout: "piped",
|
||||
stderr: "piped",
|
||||
});
|
||||
|
||||
|
||||
const { code, stdout, stderr } = await command.output();
|
||||
|
||||
|
||||
if (code !== 0 && code !== 1) { // Deno lint returns 1 when there are lint issues
|
||||
const errorOutput = new TextDecoder().decode(stderr);
|
||||
throw new Error(`Lint command failed:\n${errorOutput}`);
|
||||
}
|
||||
|
||||
|
||||
const output = new TextDecoder().decode(stdout);
|
||||
return JSON.parse(output);
|
||||
}
|
||||
@@ -167,13 +170,13 @@ async function main() {
|
||||
g: "group",
|
||||
h: "help",
|
||||
s: "stats",
|
||||
l: "limit"
|
||||
l: "limit",
|
||||
},
|
||||
string: ["file", "code", "group"],
|
||||
boolean: ["help", "stats"],
|
||||
default: { limit: 0 } // 0 means no limit
|
||||
default: { limit: 0 }, // 0 means no limit
|
||||
});
|
||||
|
||||
|
||||
if (args.help) {
|
||||
console.log(`
|
||||
Usage: deno run analyze_lint.ts [options] [lint-output.json]
|
||||
@@ -195,9 +198,9 @@ Examples:
|
||||
`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let lintResult: LintResult;
|
||||
|
||||
|
||||
// Read from file or run lint command
|
||||
if (args._.length > 0) {
|
||||
const filePath = String(args._[0]);
|
||||
@@ -206,44 +209,51 @@ Examples:
|
||||
} else {
|
||||
lintResult = await runDenoLint();
|
||||
}
|
||||
|
||||
|
||||
// Apply filters
|
||||
const filterOptions: FilterOptions = {};
|
||||
if (args.code) {
|
||||
filterOptions.codes = args.code.split(",").map(c => c.trim());
|
||||
filterOptions.codes = args.code.split(",").map((c) => c.trim());
|
||||
}
|
||||
if (args.file) {
|
||||
// Handle multiple file patterns
|
||||
filterOptions.files = Array.isArray(args.file)
|
||||
? args.file
|
||||
: [args.file];
|
||||
filterOptions.files = Array.isArray(args.file) ? args.file : [args.file];
|
||||
}
|
||||
|
||||
|
||||
const filteredDiagnostics = filterDiagnostics(
|
||||
lintResult.diagnostics,
|
||||
filterOptions
|
||||
filterOptions,
|
||||
);
|
||||
|
||||
|
||||
// Show statistics if requested
|
||||
if (args.stats) {
|
||||
const stats = calculateStats(filteredDiagnostics);
|
||||
printStats(stats);
|
||||
}
|
||||
|
||||
|
||||
// Group or show all diagnostics
|
||||
if (args.group) {
|
||||
const groups = groupDiagnostics(filteredDiagnostics, args.group as "code" | "file");
|
||||
printGroupedDiagnostics(groups, args.group as "code" | "file", (args.limit as number) || undefined);
|
||||
const groups = groupDiagnostics(
|
||||
filteredDiagnostics,
|
||||
args.group as "code" | "file",
|
||||
);
|
||||
printGroupedDiagnostics(
|
||||
groups,
|
||||
args.group as "code" | "file",
|
||||
(args.limit as number) || undefined,
|
||||
);
|
||||
} else if (!args.stats) {
|
||||
// Only show JSON output if neither stats nor grouping is requested
|
||||
console.log(JSON.stringify({ diagnostics: filteredDiagnostics }, null, 2));
|
||||
}
|
||||
|
||||
|
||||
if (!args.stats) {
|
||||
console.log(`\nFound ${filteredDiagnostics.length} issues matching criteria`);
|
||||
console.log(
|
||||
`\nFound ${filteredDiagnostics.length} issues matching criteria`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (import.meta.main) {
|
||||
main().catch(console.error);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user