diff --git a/packages/docs/src/content/docs/features/reporters.md b/packages/docs/src/content/docs/features/reporters.md index 9bc7f92d9..3e8d9725d 100644 --- a/packages/docs/src/content/docs/features/reporters.md +++ b/packages/docs/src/content/docs/features/reporters.md @@ -91,16 +91,16 @@ markdown tables separated by issue types as headings, for example: ## Unlisted dependencies (2) -| Name | Location | -| :-------------- | :----------- | -| unresolved | src/index.ts | -| @org/unresolved | src/index.ts | +| Name | Location | Severity | +| :-------------- | :---------------- | :------- | +| unresolved | src/index.ts:8:23 | error | +| @org/unresolved | src/index.ts:9:23 | error | ## Unresolved imports (1) -| Name | Location | -| :----------- | :----------- | -| ./unresolved | src/index.ts | +| Name | Location | Severity | +| :----------- | :----------------- | :------- | +| ./unresolved | src/index.ts:10:12 | error | ``` ## Custom Reporters @@ -170,7 +170,7 @@ line (can be repeated). The default export of the preprocessor should be a function with this interface: ```ts -type Preprocessor = async (options: ReporterOptions) => ReporterOptions; +type Preprocessor = async (options: ReporterOptions) => ReporterOptions; ``` Like reporters, you can use local JavaScript or TypeScript files and external diff --git a/packages/knip/src/reporters/markdown.ts b/packages/knip/src/reporters/markdown.ts index 7ea5abbd1..7e92339bb 100644 --- a/packages/knip/src/reporters/markdown.ts +++ b/packages/knip/src/reporters/markdown.ts @@ -6,6 +6,13 @@ import type { Entries } from 'type-fest'; export default ({ report, issues }: ReporterOptions) => { console.log('# Knip report\n'); + const getFilePath = (issue: Issue) => { + if (!issue.line || !issue.col) return relative(issue.filePath); + return `${relative(issue.filePath)}:${issue.line}:${issue.col}`; + }; + const sortLongestSymbol = (a: Issue, b: Issue) => b.symbol.length - a.symbol.length; + const sortLongestFilePath = (a: Issue, b: Issue) => getFilePath(b).length - getFilePath(a).length; + for (const [reportType, isReportType] of Object.entries(report) as Entries) { if (isReportType) { const title = getTitle(reportType); @@ -21,16 +28,17 @@ export default ({ report, issues }: ReporterOptions) => { console.log(`* ${toRelative(issue)}`); }); } else { - const longestSymbol = issuesForType.sort((a, b) => b.symbol.length - a.symbol.length)[0].symbol.length; - const longestFilePath = relative( - issuesForType.sort((a, b) => relative(b.filePath).length - relative(a.filePath).length)[0].filePath - ).length; - const sortedByFilePath = issuesForType.sort((a, b) => (a.filePath > b.filePath ? 1 : -1)); - console.log(`| ${`Name`.padEnd(longestSymbol)} | ${`Location`.padEnd(longestFilePath)} |`); - console.log(`|:${'-'.repeat(longestSymbol + 1)}|:${'-'.repeat(longestFilePath + 1)}|`); + const longestSymbol = issuesForType.sort(sortLongestSymbol)[0].symbol.length; + const sortedByFilePath = issuesForType.sort(sortLongestFilePath); + const longestFilePath = getFilePath(sortedByFilePath[0]).length; + + console.log(`| ${`Name`.padEnd(longestSymbol)} | ${`Location`.padEnd(longestFilePath)} | Severity |`); + console.log(`| :${'-'.repeat(longestSymbol - 1)} | :${'-'.repeat(longestFilePath - 1)} | :------- |`); sortedByFilePath.forEach((issue: Issue) => { console.log( - `| ${issue.symbol.padEnd(longestSymbol)} | ${relative(issue.filePath).padEnd(longestFilePath)} |` + `| ${issue.symbol.padEnd(longestSymbol)} | ${getFilePath(issue).padEnd(longestFilePath)} | ${( + issue.severity ?? '' + ).padEnd(8)} |` ); }); } diff --git a/packages/knip/test/cli-reporter-markdown.test.ts b/packages/knip/test/cli-reporter-markdown.test.ts index eaed33da3..98c8d097d 100644 --- a/packages/knip/test/cli-reporter-markdown.test.ts +++ b/packages/knip/test/cli-reporter-markdown.test.ts @@ -16,16 +16,16 @@ test('knip --reporter markdown', () => { ## Unlisted dependencies (2) -| Name | Location | -|:----------------|:-------------| -| unresolved | src/index.ts | -| @org/unresolved | src/index.ts | +| Name | Location | Severity | +| :-------------- | :----------- | :------- | +| @org/unresolved | src/index.ts | error | +| unresolved | src/index.ts | error | ## Unresolved imports (1) -| Name | Location | -|:-------------|:-------------| -| ./unresolved | src/index.ts | +| Name | Location | Severity | +| :----------- | :---------------- | :------- | +| ./unresolved | src/index.ts:8:23 | error | `; const out = exec('knip --reporter markdown').stdout;