Skip to content

Commit

Permalink
Merge pull request #232 from bmish/col-options
Browse files Browse the repository at this point in the history
Add optional column and notice to indicate whether a rule is configurable
  • Loading branch information
bmish committed Nov 17, 2022
2 parents 8660ffc + 1c72c66 commit f3aaabc
Show file tree
Hide file tree
Showing 14 changed files with 140 additions and 8 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@ These can be provided as CLI options or as [config file](#configuration-file) op
| `--ignore-deprecated-rules` | Whether to ignore deprecated rules from being checked, displayed, or updated (default: `false`). |
| `--path-rule-doc` | Path to markdown file for each rule doc. Use `{name}` placeholder for the rule name (default: `docs/rules/{name}.md`). |
| `--path-rule-list` | Path to markdown file with a rules section where the rules table list should live (default: `README.md`). |
| `--rule-doc-notices` | Ordered, comma-separated list of notices to display in rule doc. Non-applicable notices will be hidden. Choices: `configs`, `deprecated`, `fixable` (off by default), `fixableAndHasSuggestions`, `hasSuggestions` (off by default), `requiresTypeChecking`, `type` (off by default). Default: `deprecated,configs,fixableAndHasSuggestions,requiresTypeChecking`. |
| `--rule-doc-notices` | Ordered, comma-separated list of notices to display in rule doc. Non-applicable notices will be hidden. Choices: `configs`, `deprecated`, `fixable` (off by default), `fixableAndHasSuggestions`, `hasSuggestions` (off by default), `options` (off by default), `requiresTypeChecking`, `type` (off by default). Default: `deprecated,configs,fixableAndHasSuggestions,requiresTypeChecking`. |
| `--rule-doc-section-exclude` | Disallowed section in each rule doc. Exit with failure if present. Option can be repeated. |
| `--rule-doc-section-include` | Required section in each rule doc. Exit with failure if missing. Option can be repeated. |
| `--rule-doc-section-options` | Whether to require an "Options" or "Config" rule doc section and mention of any named options for rules with options (default: `true`). |
| `--rule-doc-title-format` | The format to use for rule doc titles. Defaults to `desc-parens-prefix-name`. See choices in below [table](#--rule-doc-title-format). |
| `--rule-list-columns` | Ordered, comma-separated list of columns to display in rule list. Empty columns will be hidden. Choices: `configsError`, `configsOff`, `configsWarn`, `deprecated`, `description`, `fixable`, `fixableAndHasSuggestions` (off by default), `hasSuggestions`, `name`, `requiresTypeChecking`, `type` (off by default). Default: `name,description,configsError,configsWarn,configsOff,fixable,hasSuggestions,requiresTypeChecking,deprecated`. |
| `--rule-list-columns` | Ordered, comma-separated list of columns to display in rule list. Empty columns will be hidden. Choices: `configsError`, `configsOff`, `configsWarn`, `deprecated`, `description`, `fixable`, `fixableAndHasSuggestions` (off by default), `hasSuggestions`, `name`, `options` (off by default), `requiresTypeChecking`, `type` (off by default). Default: `name,description,configsError,configsWarn,configsOff,fixable,hasSuggestions,requiresTypeChecking,deprecated`. |
| `--split-by` | Rule property to split the rules list by. A separate list and header will be created for each value. Example: `meta.type`. |
| `--url-configs` | Link to documentation about the ESLint configurations exported by the plugin. |

Expand Down
11 changes: 6 additions & 5 deletions docs/examples/eslint-plugin-test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ Configs section would normally go here.
⌨️ Set in the `typescript` configuration.\
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
💡 Manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).\
⚙️ Has configuration options.\
💭 Requires type information.\
🗂️ The type of rule.\
❗ Identifies problems that could cause errors or unexpected behavior.\
📖 Identifies potential improvements.\
📏 Focuses on code formatting.\
❌ Deprecated.

| Name | Description | 💼 | ⚠️ | 🚫 | 🔧 | 💡 | 💭 | 🗂️ ||
| :--------------------------------------- | :----------------- | :- | :- | :- | :- | :- | :- | :-- | :- |
| [no-foo](docs/rules/no-foo.md) | disallow using foo || | | 🔧 | | 💭 || |
| [prefer-bar](docs/rules/prefer-bar.md) | enforce using bar || 🎨 | | | 💡 | 💭 | 📖 | |
| [require-baz](docs/rules/require-baz.md) | require using baz | | | ⌨️ | 🔧 | | | 📏 ||
| Name | Description | 💼 | ⚠️ | 🚫 | 🔧 | 💡 | ⚙️ | 💭 | 🗂️ ||
| :--------------------------------------- | :----------------- | :- | :- | :- | :- | :- | :- | :- | :-- | :- |
| [no-foo](docs/rules/no-foo.md) | disallow using foo || | | 🔧 | | ⚙️ | 💭 || |
| [prefer-bar](docs/rules/prefer-bar.md) | enforce using bar || 🎨 | | | 💡 | | 💭 | 📖 | |
| [require-baz](docs/rules/require-baz.md) | require using baz | | | ⌨️ | 🔧 | | | | 📏 ||

<!-- end auto-generated rules list -->
4 changes: 4 additions & 0 deletions docs/examples/eslint-plugin-test/docs/rules/no-foo.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

⚙️ This rule is configurable.

💭 This rule requires type information.

❗ This rule identifies problems that could cause errors or unexpected behavior.

<!-- end auto-generated rule header -->

## Rule details
Expand Down
2 changes: 2 additions & 0 deletions docs/examples/eslint-plugin-test/docs/rules/prefer-bar.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

💭 This rule requires type information.

📖 This rule identifies potential improvements.

<!-- end auto-generated rule header -->

## Rule details
Expand Down
2 changes: 2 additions & 0 deletions docs/examples/eslint-plugin-test/docs/rules/require-baz.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

📏 This rule focuses on code formatting.

<!-- end auto-generated rule header -->

## Rule details
Expand Down
4 changes: 4 additions & 0 deletions lib/emojis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ export const EMOJI_CONFIG_FROM_SEVERITY: {
export const EMOJI_FIXABLE = '🔧';
export const EMOJI_HAS_SUGGESTIONS = '💡';

// Options.
export const EMOJI_OPTIONS = '⚙️';

// TypeScript.
export const EMOJI_REQUIRES_TYPE_CHECKING = '💭';

Expand All @@ -58,6 +61,7 @@ export const RESERVED_EMOJIS = [

EMOJI_FIXABLE,
EMOJI_HAS_SUGGESTIONS,
EMOJI_OPTIONS,
EMOJI_REQUIRES_TYPE_CHECKING,
EMOJI_TYPE,
EMOJI_DEPRECATED,
Expand Down
2 changes: 2 additions & 0 deletions lib/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
EMOJI_DEPRECATED,
EMOJI_FIXABLE,
EMOJI_HAS_SUGGESTIONS,
EMOJI_OPTIONS,
EMOJI_REQUIRES_TYPE_CHECKING,
EMOJI_TYPE,
EMOJI_CONFIG_FROM_SEVERITY,
Expand Down Expand Up @@ -139,6 +140,7 @@ const LEGENDS: {
],
[COLUMN_TYPE.HAS_SUGGESTIONS]: [LEGEND_HAS_SUGGESTIONS],
[COLUMN_TYPE.NAME]: undefined,
[COLUMN_TYPE.OPTIONS]: [`${EMOJI_OPTIONS} Has configuration options.`],
[COLUMN_TYPE.REQUIRES_TYPE_CHECKING]: [
`${EMOJI_REQUIRES_TYPE_CHECKING} Requires type information.`,
],
Expand Down
2 changes: 2 additions & 0 deletions lib/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const COLUMN_TYPE_DEFAULT_PRESENCE_AND_ORDERING: {
[COLUMN_TYPE.FIXABLE]: true,
[COLUMN_TYPE.FIXABLE_AND_HAS_SUGGESTIONS]: false, // Optional, consolidated column.
[COLUMN_TYPE.HAS_SUGGESTIONS]: true,
[COLUMN_TYPE.OPTIONS]: false,
[COLUMN_TYPE.REQUIRES_TYPE_CHECKING]: true,
[COLUMN_TYPE.TYPE]: false,
[COLUMN_TYPE.DEPRECATED]: true,
Expand All @@ -29,6 +30,7 @@ export const NOTICE_TYPE_DEFAULT_PRESENCE_AND_ORDERING: {
[NOTICE_TYPE.FIXABLE]: false,
[NOTICE_TYPE.FIXABLE_AND_HAS_SUGGESTIONS]: true, // Default, consolidated notice.
[NOTICE_TYPE.HAS_SUGGESTIONS]: false,
[NOTICE_TYPE.OPTIONS]: false,
[NOTICE_TYPE.REQUIRES_TYPE_CHECKING]: true,
[NOTICE_TYPE.TYPE]: false,
};
Expand Down
4 changes: 4 additions & 0 deletions lib/rule-list-columns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import {
EMOJI_REQUIRES_TYPE_CHECKING,
EMOJI_TYPE,
EMOJI_CONFIG_FROM_SEVERITY,
EMOJI_OPTIONS,
} from './emojis.js';
import { RULE_TYPES } from './rule-type.js';
import { COLUMN_TYPE, SEVERITY_TYPE } from './types.js';
import { getConfigsThatSetARule } from './configs.js';
import { hasOptions } from './rule-options.js';
import type { RuleDetails, ConfigsToRules, Plugin } from './types.js';

/**
Expand Down Expand Up @@ -52,6 +54,7 @@ export const COLUMN_HEADER: {
[COLUMN_TYPE.FIXABLE]: EMOJI_FIXABLE,
[COLUMN_TYPE.FIXABLE_AND_HAS_SUGGESTIONS]: `${EMOJI_FIXABLE}${EMOJI_HAS_SUGGESTIONS}`,
[COLUMN_TYPE.HAS_SUGGESTIONS]: EMOJI_HAS_SUGGESTIONS,
[COLUMN_TYPE.OPTIONS]: EMOJI_OPTIONS,
[COLUMN_TYPE.REQUIRES_TYPE_CHECKING]: EMOJI_REQUIRES_TYPE_CHECKING,
[COLUMN_TYPE.TYPE]: EMOJI_TYPE,
};
Expand Down Expand Up @@ -106,6 +109,7 @@ export function getColumns(
(detail) => detail.hasSuggestions
),
[COLUMN_TYPE.NAME]: true,
[COLUMN_TYPE.OPTIONS]: details.some((detail) => hasOptions(detail.schema)),
[COLUMN_TYPE.REQUIRES_TYPE_CHECKING]: details.some(
(detail) => detail.requiresTypeChecking
),
Expand Down
3 changes: 3 additions & 0 deletions lib/rule-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
EMOJI_DEPRECATED,
EMOJI_FIXABLE,
EMOJI_HAS_SUGGESTIONS,
EMOJI_OPTIONS,
EMOJI_REQUIRES_TYPE_CHECKING,
} from './emojis.js';
import { getConfigsForRule, findConfigEmoji } from './configs.js';
Expand All @@ -21,6 +22,7 @@ import type {
ConfigEmojis,
} from './types.js';
import { EMOJIS_TYPE, RULE_TYPE } from './rule-type.js';
import { hasOptions } from './rule-options.js';

// Example: theWeatherIsNice => The Weather Is Nice
function camelCaseStringToTitle(str: string) {
Expand Down Expand Up @@ -166,6 +168,7 @@ function buildRuleRow(
/{name}/g,
rule.name
)})`,
[COLUMN_TYPE.OPTIONS]: hasOptions(rule.schema) ? EMOJI_OPTIONS : '',
[COLUMN_TYPE.REQUIRES_TYPE_CHECKING]: rule.requiresTypeChecking
? EMOJI_REQUIRES_TYPE_CHECKING
: '',
Expand Down
5 changes: 5 additions & 0 deletions lib/rule-notices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
EMOJI_HAS_SUGGESTIONS,
EMOJI_REQUIRES_TYPE_CHECKING,
EMOJI_CONFIG_FROM_SEVERITY,
EMOJI_OPTIONS,
} from './emojis.js';
import { findConfigEmoji, getConfigsForRule } from './configs.js';
import {
Expand All @@ -17,6 +18,7 @@ import {
} from './types.js';
import { RULE_TYPE, RULE_TYPE_MESSAGES_NOTICES } from './rule-type.js';
import { RuleDocTitleFormat } from './rule-doc-title-format.js';
import { hasOptions } from './rule-options.js';

function severityToTerminology(severity: SEVERITY_TYPE) {
switch (severity) {
Expand Down Expand Up @@ -194,6 +196,7 @@ const RULE_NOTICES: {
},
[NOTICE_TYPE.HAS_SUGGESTIONS]: NOTICE_HAS_SUGGESTIONS,

[NOTICE_TYPE.OPTIONS]: `${EMOJI_OPTIONS} This rule is configurable.`,
[NOTICE_TYPE.REQUIRES_TYPE_CHECKING]: `${EMOJI_REQUIRES_TYPE_CHECKING} This rule requires type information.`,
};

Expand Down Expand Up @@ -241,11 +244,13 @@ function getNoticesForRule(
configsOff.length > 0,
[NOTICE_TYPE.DEPRECATED]: rule.meta?.deprecated || false,

// Fixable/suggestions.
[NOTICE_TYPE.FIXABLE]: Boolean(rule.meta?.fixable),
[NOTICE_TYPE.FIXABLE_AND_HAS_SUGGESTIONS]:
Boolean(rule.meta?.fixable) || Boolean(rule.meta?.hasSuggestions),
[NOTICE_TYPE.HAS_SUGGESTIONS]: Boolean(rule.meta?.hasSuggestions),

[NOTICE_TYPE.OPTIONS]: hasOptions(rule.meta?.schema),
[NOTICE_TYPE.REQUIRES_TYPE_CHECKING]:
rule.meta?.docs?.requiresTypeChecking || false,
[NOTICE_TYPE.TYPE]: Boolean(rule.meta?.type),
Expand Down
3 changes: 2 additions & 1 deletion lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ export type ConfigEmojis = { config: string; emoji: string }[];

/**
* Rule doc notices.
* Same as COLUMN_TYPE but without NAME, DESCRIPTION (which are in the rule doc title).
*/
export enum NOTICE_TYPE {
CONFIGS = 'configs',
DEPRECATED = 'deprecated',
FIXABLE = 'fixable',
FIXABLE_AND_HAS_SUGGESTIONS = 'fixableAndHasSuggestions', // Consolidated notice for space-saving.
HAS_SUGGESTIONS = 'hasSuggestions',
OPTIONS = 'options',
REQUIRES_TYPE_CHECKING = 'requiresTypeChecking',
TYPE = 'type',
}
Expand All @@ -77,6 +77,7 @@ export enum COLUMN_TYPE {
FIXABLE_AND_HAS_SUGGESTIONS = 'fixableAndHasSuggestions', // Consolidated column for space-saving.
HAS_SUGGESTIONS = 'hasSuggestions',
NAME = 'name',
OPTIONS = 'options',
REQUIRES_TYPE_CHECKING = 'requiresTypeChecking',
TYPE = 'type',
}
51 changes: 51 additions & 0 deletions test/lib/__snapshots__/generator-test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,57 @@ exports[`generator #generate rule with no meta object generates the documentatio
"
`;

exports[`generator #generate rule with options, options column/notice enabled displays the column and notice 1`] = `
"## Rules
<!-- begin auto-generated rules list -->
⚙️ Has configuration options.
| Name | ⚙️ |
| :----------------------------- | :- |
| [no-bar](docs/rules/no-bar.md) | ⚙️ |
| [no-baz](docs/rules/no-baz.md) | |
| [no-biz](docs/rules/no-biz.md) | |
| [no-foo](docs/rules/no-foo.md) | ⚙️ |
<!-- end auto-generated rules list -->
"
`;

exports[`generator #generate rule with options, options column/notice enabled displays the column and notice 2`] = `
"# test/no-foo
⚙️ This rule is configurable.
<!-- end auto-generated rule header -->
## Options
"
`;

exports[`generator #generate rule with options, options column/notice enabled displays the column and notice 3`] = `
"# test/no-bar
⚙️ This rule is configurable.
<!-- end auto-generated rule header -->
## Options
"
`;

exports[`generator #generate rule with options, options column/notice enabled displays the column and notice 4`] = `
"# test/no-biz
<!-- end auto-generated rule header -->
"
`;

exports[`generator #generate rule with options, options column/notice enabled displays the column and notice 5`] = `
"# test/no-baz
<!-- end auto-generated rule header -->
"
`;

exports[`generator #generate rule with type, type column enabled displays the type 1`] = `
"## Rules
<!-- begin auto-generated rules list -->
Expand Down
51 changes: 51 additions & 0 deletions test/lib/generator-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4077,6 +4077,57 @@ describe('generator', function () {
});
});

describe('rule with options, options column/notice enabled', function () {
beforeEach(function () {
mockFs({
'package.json': JSON.stringify({
name: 'eslint-plugin-test',
main: 'index.js',
type: 'module',
}),

'index.js': `
export default {
rules: {
'no-foo': { meta: { schema: [{foo:true}] }, create(context) {} },
'no-bar': { meta: { schema: {foo:true} }, create(context) {} },
'no-biz': { meta: { schema: [] }, create(context) {} },
'no-baz': { meta: { }, create(context) {} },
},
};`,

'README.md': '## Rules\n',

'docs/rules/no-foo.md': '## Options\n',
'docs/rules/no-bar.md': '## Options\n',
'docs/rules/no-biz.md': '',
'docs/rules/no-baz.md': '',

// Needed for some of the test infrastructure to work.
node_modules: mockFs.load(
resolve(__dirname, '..', '..', 'node_modules')
),
});
});

afterEach(function () {
mockFs.restore();
jest.resetModules();
});

it('displays the column and notice', async function () {
await generate('.', {
ruleListColumns: 'name,options',
ruleDocNotices: 'options',
});
expect(readFileSync('README.md', 'utf8')).toMatchSnapshot();
expect(readFileSync('docs/rules/no-foo.md', 'utf8')).toMatchSnapshot();
expect(readFileSync('docs/rules/no-bar.md', 'utf8')).toMatchSnapshot();
expect(readFileSync('docs/rules/no-biz.md', 'utf8')).toMatchSnapshot();
expect(readFileSync('docs/rules/no-baz.md', 'utf8')).toMatchSnapshot();
});
});

describe('rule with long-enough description to require name column wrapping avoidance', function () {
beforeEach(function () {
mockFs({
Expand Down

0 comments on commit f3aaabc

Please sign in to comment.