Skip to content

Commit

Permalink
Merge pull request #54 from mizdra/print-documentation-link
Browse files Browse the repository at this point in the history
Print documentation links of rule
  • Loading branch information
mizdra committed Nov 20, 2021
2 parents 4701ad0 + d703a63 commit fc1ee09
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 16 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ jobs:
id: cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.OS }}-yarn-
key: build-${{ runner.os }}-${{ matrix.node }}-yarn-${{ hashFiles('**/yarn.lock') }}-${{ matrix.eslint }}
restore-keys: build-${{ runner.OS }}-${{ matrix.node }}-yarn-

- name: yarn install --frozen-lockfile
run: yarn install --frozen-lockfile
Expand Down Expand Up @@ -51,8 +51,8 @@ jobs:
id: cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: test-${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: test-${{ runner.OS }}-yarn-
key: test-${{ runner.os }}-${{ matrix.node }}-yarn-${{ hashFiles('**/yarn.lock') }}-${{ matrix.eslint }}
restore-keys: test-${{ runner.OS }}-${{ matrix.node }}-yarn-

- name: yarn install --frozen-lockfile
run: yarn install --frozen-lockfile
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@mizdra/eslint-config-mizdra": "^1.0.0",
"@mizdra/prettier-config-mizdra": "^0.4.0",
"@types/cli-table": "^0.3.0",
"@types/eslint": "^7.28.2",
"@types/eslint": "^8.2.0",
"@types/estree": "^0.0.50",
"@types/jest": "^27.0.2",
"@types/node": "^14.14.10",
Expand All @@ -43,7 +43,7 @@
"typescript": "^4.1.2"
},
"dependencies": {
"cli-table": "^0.3.6",
"cli-table": "^0.3.8",
"enquirer": "^2.3.6",
"eslint-formatter-codeframe": "^7.32.1",
"node-pager": "^0.3.6",
Expand Down
16 changes: 14 additions & 2 deletions src/eslint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DisableTarget, Option } from './rules/add-disable-comment';
import { ApplySuggestionOption } from './rules/apply-suggestion';
import { DisplayMode } from './types';
import { groupBy } from './util/array';
import { scanUsedPluginsFromResults } from './util/eslint';
import { notEmpty } from './util/filter';

function filterResultsByRuleId(results: ESLint.LintResult[], ruleIds: string[]): ESLint.LintResult[] {
Expand Down Expand Up @@ -72,7 +73,6 @@ function createApplySuggestionESLint(
});
return eslint;
}

type CachedESLintOptions = {
rulePaths?: string[];
extensions?: string[];
Expand Down Expand Up @@ -103,7 +103,19 @@ export class CachedESLint {
}

printResults(results: ESLint.LintResult[]): void {
const resultText = format(results);
// get used plugins from `results`
const plugins = scanUsedPluginsFromResults(results);

// get `rulesMeta` from `results`
const eslint = new ESLint({
...this.defaultOptions,
overrideConfig: { plugins },
});
// NOTE: `getRulesMetaForResults` is a feature added in ESLint 7.29.0.
// Therefore, the function may not exist in versions lower than 7.29.0.
const rulesMeta: ESLint.LintResultData['rulesMeta'] = eslint.getRulesMetaForResults?.(results) ?? {};

const resultText = format(results, { rulesMeta: rulesMeta });
console.log(resultText);
}

Expand Down
20 changes: 20 additions & 0 deletions src/util/eslint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ESLint } from 'eslint';
import { unique } from './array';
import { notEmpty } from './filter';

/** `results` 内で使われているプラグインの名前のリストを洗い出して返す */
export function scanUsedPluginsFromResults(results: ESLint.LintResult[]): string[] {
const plugins = results
.flatMap((result) => result.messages) // messages: Linter.LintMessage[]
.map((message) => message.ruleId) // ruleIds: (string | undefined)[]
.filter(notEmpty) // ruleIds: string[]
.map((ruleId) => {
const parts = ruleId.split('/');
if (parts.length === 1) return undefined; // ex: 'rule-a'
if (parts.length === 2) return parts[0]; // ex: 'plugin/rule-a'
if (parts.length === 3) return `${parts[0]}/${parts[1]}`; // ex: '@scoped/plugin/rule-a'
return undefined; // invalid ruleId
}) // plugins: string[]
.filter(notEmpty);
return unique(plugins);
}
40 changes: 40 additions & 0 deletions test/formatter/format-by-rules.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-irregular-whitespace */
import { ESLint } from 'eslint';
import stripAnsi from 'strip-ansi';
import { formatByRules } from '../../src/formatter/format-by-rules';
Expand Down Expand Up @@ -43,6 +44,45 @@ describe('formatByRules', () => {
├────────┼────────────────────────────────────┼──────────────────────────────────────┤
│ rule-b │ 1 (0/0) │ 0 (0/0) │
└────────┴────────────────────────────────────┴──────────────────────────────────────┘"
`);
});
test('prints link', () => {
const results: ESLint.LintResult[] = [
fakeLintResult({
messages: [
fakeLintMessage({ ruleId: 'rule-a', severity: 2 }), // link is printed
fakeLintMessage({ ruleId: 'rule-b', severity: 2 }), // no link is printed
fakeLintMessage({ ruleId: 'plugin/rule-c', severity: 2 }), // link is printed
],
}),
];
const formattedText = formatByRules(results, {
rulesMeta: {
'rule-a': { docs: { url: 'https://example.com/rule-a' } },
'plugin/rule-c': { docs: { url: 'https://example.com/plugin/rule-c' } },
},
});
expect(stripAnsi(formattedText)).toMatchInlineSnapshot(`
"┌─────────────────────────────────────────────────────┬────────────────────────────────────┬──────────────────────────────────────┐
│ Rule │ Error (fixable/suggest-applicable) │ Warning (fixable/suggest-applicable) │
├─────────────────────────────────────────────────────┼────────────────────────────────────┼──────────────────────────────────────┤
│ rule-a (​https://example.com/rule-a​) │ 1 (0/0) │ 0 (0/0) │
├─────────────────────────────────────────────────────┼────────────────────────────────────┼──────────────────────────────────────┤
│ rule-b │ 1 (0/0) │ 0 (0/0) │
├─────────────────────────────────────────────────────┼────────────────────────────────────┼──────────────────────────────────────┤
│ plugin/rule-c (​https://example.com/plugin/rule-c​) │ 1 (0/0) │ 0 (0/0) │
└─────────────────────────────────────────────────────┴────────────────────────────────────┴──────────────────────────────────────┘"
`);
expect(formattedText).toMatchInlineSnapshot(`
"┌─────────────────────────────────────────────────────┬────────────────────────────────────┬──────────────────────────────────────┐
│ Rule │ Error (fixable/suggest-applicable) │ Warning (fixable/suggest-applicable) │
├─────────────────────────────────────────────────────┼────────────────────────────────────┼──────────────────────────────────────┤
│ rule-a (​https://example.com/rule-a​) │ 1 (0/0) │ 0 (0/0) │
├─────────────────────────────────────────────────────┼────────────────────────────────────┼──────────────────────────────────────┤
│ rule-b │ 1 (0/0) │ 0 (0/0) │
├─────────────────────────────────────────────────────┼────────────────────────────────────┼──────────────────────────────────────┤
│ plugin/rule-c (​https://example.com/plugin/rule-c​) │ 1 (0/0) │ 0 (0/0) │
└─────────────────────────────────────────────────────┴────────────────────────────────────┴──────────────────────────────────────┘"
`);
});
});
17 changes: 17 additions & 0 deletions test/util/eslint.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ESLint } from 'eslint';
import { scanUsedPluginsFromResults } from '../../src/util/eslint';
import { fakeLintMessage, fakeLintResult } from '../test-util/eslint';

test('scanUsedPluginsFromResults', () => {
const results: ESLint.LintResult[] = [
fakeLintResult({
messages: [
fakeLintMessage({ ruleId: 'rule', severity: 2 }),
fakeLintMessage({ ruleId: 'plugin/rule', severity: 2 }),
fakeLintMessage({ ruleId: '@scoped/plugin/rule', severity: 2 }),
fakeLintMessage({ ruleId: 'invalid/@scoped/plugin/rule', severity: 2 }),
],
}),
];
expect(scanUsedPluginsFromResults(results)).toStrictEqual(['plugin', '@scoped/plugin']);
});
29 changes: 21 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -611,10 +611,10 @@
resolved "https://registry.yarnpkg.com/@types/cli-table/-/cli-table-0.3.0.tgz#f1857156bf5fd115c6a2db260ba0be1f8fc5671c"
integrity sha512-QnZUISJJXyhyD6L1e5QwXDV/A5i2W1/gl6D6YMc8u0ncPepbv/B4w3S+izVvtAg60m6h+JP09+Y/0zF2mojlFQ==

"@types/eslint@^7.28.2":
version "7.28.2"
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.28.2.tgz#0ff2947cdd305897c52d5372294e8c76f351db68"
integrity sha512-KubbADPkfoU75KgKeKLsFHXnU4ipH7wYg0TRT33NK3N3yiu7jlFAAoygIWBV+KbuHx/G+AvuGX6DllnK35gfJA==
"@types/eslint@^8.2.0":
version "8.2.0"
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.0.tgz#afd0519223c29c347087542cbaee2fedc0873b16"
integrity sha512-74hbvsnc+7TEDa1z5YLSe4/q8hGYB3USNvCuzHUJrjPV6hXaq8IXcngCrHkuvFt0+8rFz7xYXrHgNayIX0UZvQ==
dependencies:
"@types/estree" "*"
"@types/json-schema" "*"
Expand Down Expand Up @@ -839,6 +839,11 @@ ansi-regex@^5.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==

ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==

ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
Expand Down Expand Up @@ -1096,12 +1101,13 @@ cli-spinners@^2.4.0:
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.5.0.tgz#12763e47251bf951cb75c201dfa58ff1bcb2d047"
integrity sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ==

cli-table@^0.3.6:
version "0.3.6"
resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.6.tgz#e9d6aa859c7fe636981fd3787378c2a20bce92fc"
integrity sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ==
cli-table@^0.3.8:
version "0.3.8"
resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.8.tgz#d3629cbf893459a8ad99671554e702a1c6d48a01"
integrity sha512-5IO15fJRzgM+hHZjvQlqD6UPRuVGWR4Ny5ZzaM5VJxJEQqSIEVyVh9dMAUN6CBAVfMc4/6CFEzbhnRftLRCyug==
dependencies:
colors "1.0.3"
strip-ansi "^6.0.1"

cliui@^7.0.2:
version "7.0.4"
Expand Down Expand Up @@ -3485,6 +3491,13 @@ strip-ansi@^6.0.0:
dependencies:
ansi-regex "^5.0.0"

strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
Expand Down

0 comments on commit fc1ee09

Please sign in to comment.