Skip to content

Commit

Permalink
feat: add --config-format option
Browse files Browse the repository at this point in the history
  • Loading branch information
bmish committed Dec 23, 2022
1 parent d9fe7ed commit c0c94c5
Show file tree
Hide file tree
Showing 13 changed files with 254 additions and 7 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Also performs [configurable](#configuration-options) section consistency checks
- [Users](#users)
- [Configuration options](#configuration-options)
- [Column and notice types](#column-and-notice-types)
- [`--config-format`](#--config-format)
- [`--rule-doc-title-format`](#--rule-doc-title-format)
- [Configuration file](#configuration-file)
- [Badges](#badges)
Expand Down Expand Up @@ -131,6 +132,7 @@ There's also a `postprocess` option that's only available via a [config file](#c
| :-- | :-- |
| `--check` | Whether to check for and fail if there is a diff. No output will be written. Typically used during CI. Default: `false`. |
| `--config-emoji` | Custom emoji to use for a config. Format is `config-name,emoji`. Default emojis are provided for [common configs](./lib/emojis.ts). To remove a default emoji and rely on a [badge](#badges) instead, provide the config name without an emoji. Option can be repeated. |
| `--config-format` | The format to use for config names. Defaults to `name`. See choices in below [table](#--config-format). |
| `--ignore-config` | Config to ignore from being displayed. Often used for an `all` config. Option can be repeated. |
| `--ignore-deprecated-rules` | Whether to ignore deprecated rules from being checked, displayed, or updated. Default: `false`. |
| `--init-rule-docs` | Whether to create rule doc files if they don't yet exist. Default: `false`. |
Expand Down Expand Up @@ -166,6 +168,15 @@ These are the types of rule metadata that are available for display in rule list
| 💭 | `requiresTypeChecking` | Yes | Yes | Whether a rule requires [type checking](https://typescript-eslint.io/linting/typed-linting/). |
| 🗂️ | `type` | Yes | Yes | The rule [type](https://eslint.org/docs/latest/developer-guide/working-with-rules#rule-basics) (`problem`, `suggestion`, or `layout`). |

### `--config-format`

Where `recommended` is the config name and `eslint-plugin-test` is the plugin name.

| Value | Example |
| :-- | :-- |
| `name` (default) | `recommended` |
| `plugin-colon-prefix-name` | `plugin:test/recommended` |

### `--rule-doc-title-format`

Where `no-foo` is the rule name, `Disallow use of foo` is the rule description, and `eslint-plugin-test` is the plugin name.
Expand Down
10 changes: 10 additions & 0 deletions lib/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from './types.js';
import { getCurrentPackageVersion } from './package-json.js';
import { boolean, isBooleanable } from 'boolean';
import { CONFIG_FORMATS } from './config-format.js';

/**
* Used for collecting repeated CLI options into an array.
Expand Down Expand Up @@ -91,6 +92,7 @@ async function loadConfigFileOptions(): Promise<GenerateOptions> {
const properties: { [key in OPTION_TYPE]: unknown } = {
check: { type: 'boolean' },
configEmoji: schemaConfigEmoji,
configFormat: { type: 'string' },
ignoreConfig: schemaStringArray,
ignoreDeprecatedRules: { type: 'boolean' },
initRuleDocs: { type: 'boolean' },
Expand Down Expand Up @@ -187,6 +189,14 @@ export async function run(
collectCSVNested,
[]
)
.addOption(
new Option(
'--config-format <config-format>',
`(optional) The format to use for the config name. (default: ${
OPTION_DEFAULTS[OPTION_TYPE.CONFIG_FORMAT]
})`
).choices(CONFIG_FORMATS)
)
.option(
'--ignore-config <config>',
'(optional) Config to ignore from being displayed (often used for an `all` config) (option can be repeated).',
Expand Down
19 changes: 19 additions & 0 deletions lib/config-format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const CONFIG_FORMATS = ['name', 'plugin-colon-prefix-name'] as const;

export type ConfigFormat = typeof CONFIG_FORMATS[number];

export function configNameToDisplay(
configName: string,
configFormat: ConfigFormat,
pluginPrefix: string
) {
switch (configFormat) {
case 'name':
return configName;
case 'plugin-colon-prefix-name':
return `plugin:${pluginPrefix}/${configName}`;
/* istanbul ignore next -- this shouldn't happen */
default:
throw new Error(`Unhandled config format: ${String(configFormat)}`);
}
}
4 changes: 4 additions & 0 deletions lib/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ export async function generate(path: string, options?: GenerateOptions) {
// Options. Add default values as needed.
const check = options?.check ?? OPTION_DEFAULTS[OPTION_TYPE.CHECK];
const configEmojis = parseConfigEmojiOptions(plugin, options?.configEmoji);
const configFormat =
options?.configFormat ?? OPTION_DEFAULTS[OPTION_TYPE.CONFIG_FORMAT];
const ignoreConfig = stringOrArrayWithFallback(
options?.ignoreConfig,
OPTION_DEFAULTS[OPTION_TYPE.IGNORE_CONFIG]
Expand Down Expand Up @@ -224,6 +226,7 @@ export async function generate(path: string, options?: GenerateOptions) {
path,
pathRuleDoc,
configEmojis,
configFormat,
ignoreConfig,
ruleDocNotices,
ruleDocTitleFormat,
Expand Down Expand Up @@ -308,6 +311,7 @@ export async function generate(path: string, options?: GenerateOptions) {
pathToFile,
path,
configEmojis,
configFormat,
ignoreConfig,
ruleListColumns,
ruleListSplit,
Expand Down
6 changes: 5 additions & 1 deletion lib/options.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { join } from 'node:path';
import { ConfigFormat } from './config-format.js';
import { RuleDocTitleFormat } from './rule-doc-title-format.js';
import { COLUMN_TYPE, NOTICE_TYPE, OPTION_TYPE } from './types.js';

Expand Down Expand Up @@ -37,12 +38,15 @@ export const NOTICE_TYPE_DEFAULT_PRESENCE_AND_ORDERING: {
[NOTICE_TYPE.DESCRIPTION]: false,
};

// Using these variables ensures they have the correct type (not just a plain string).
const DEFAULT_RULE_DOC_TITLE_FORMAT: RuleDocTitleFormat =
'desc-parens-prefix-name'; // Using this variable ensures this default has the correct type (not just a plain string).
'desc-parens-prefix-name';
const DEFAULT_CONFIG_FORMAT: ConfigFormat = 'name';

export const OPTION_DEFAULTS = {
[OPTION_TYPE.CHECK]: false,
[OPTION_TYPE.CONFIG_EMOJI]: [],
[OPTION_TYPE.CONFIG_FORMAT]: DEFAULT_CONFIG_FORMAT,
[OPTION_TYPE.IGNORE_CONFIG]: [],
[OPTION_TYPE.IGNORE_DEPRECATED_RULES]: false,
[OPTION_TYPE.INIT_RULE_DOCS]: false,
Expand Down
30 changes: 25 additions & 5 deletions lib/rule-doc-notices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
removeTrailingPeriod,
addTrailingPeriod,
} from './string.js';
import { ConfigFormat, configNameToDisplay } from './config-format.js';

function severityToTerminology(severity: SEVERITY_TYPE) {
switch (severity) {
Expand All @@ -46,13 +47,19 @@ function configsToNoticeSentence(
severity: SEVERITY_TYPE,
configsLinkOrWord: string,
configLinkOrWord: string,
configEmojis: ConfigEmojis
configEmojis: ConfigEmojis,
configFormat: ConfigFormat,
pluginPrefix: string
): string | undefined {
// Create CSV list of configs with their emojis.
const csv = configs
.map((config) => {
const emoji = findConfigEmoji(configEmojis, config);
return `${emoji ? `${emoji} ` : ''}\`${config}\``;
return `${emoji ? `${emoji} ` : ''}\`${configNameToDisplay(
config,
configFormat,
pluginPrefix
)}\``;
})
.join(', ');

Expand Down Expand Up @@ -84,6 +91,7 @@ const RULE_NOTICES: {
configsWarn: readonly string[];
configsOff: readonly string[];
configEmojis: ConfigEmojis;
configFormat: ConfigFormat;
description?: string;
fixable: boolean;
hasSuggestions: boolean;
Expand All @@ -103,6 +111,8 @@ const RULE_NOTICES: {
configsWarn,
configsOff,
configEmojis,
configFormat,
pluginPrefix,
urlConfigs,
}) => {
// Add link to configs documentation if provided.
Expand Down Expand Up @@ -140,21 +150,27 @@ const RULE_NOTICES: {
SEVERITY_TYPE.error,
configsLinkOrWord,
configLinkOrWord,
configEmojis
configEmojis,
configFormat,
pluginPrefix
),
configsToNoticeSentence(
configsWarn,
SEVERITY_TYPE.warn,
configsLinkOrWord,
configLinkOrWord,
configEmojis
configEmojis,
configFormat,
pluginPrefix
),
configsToNoticeSentence(
configsOff,
SEVERITY_TYPE.off,
configsLinkOrWord,
configLinkOrWord,
configEmojis
configEmojis,
configFormat,
pluginPrefix
),
]
.filter(Boolean)
Expand Down Expand Up @@ -298,6 +314,7 @@ function getRuleNoticeLines(
pathPlugin: string,
pathRuleDoc: string,
configEmojis: ConfigEmojis,
configFormat: ConfigFormat,
ignoreConfig: readonly string[],
ruleDocNotices: readonly NOTICE_TYPE[],
urlConfigs?: string,
Expand Down Expand Up @@ -374,6 +391,7 @@ function getRuleNoticeLines(
configsWarn,
configsOff,
configEmojis,
configFormat,
description: rule.meta?.docs?.description,
fixable: Boolean(rule.meta?.fixable),
hasSuggestions: Boolean(rule.meta?.hasSuggestions),
Expand Down Expand Up @@ -479,6 +497,7 @@ export function generateRuleHeaderLines(
pathPlugin: string,
pathRuleDoc: string,
configEmojis: ConfigEmojis,
configFormat: ConfigFormat,
ignoreConfig: readonly string[],
ruleDocNotices: readonly NOTICE_TYPE[],
ruleDocTitleFormat: RuleDocTitleFormat,
Expand All @@ -495,6 +514,7 @@ export function generateRuleHeaderLines(
pathPlugin,
pathRuleDoc,
configEmojis,
configFormat,
ignoreConfig,
ruleDocNotices,
urlConfigs,
Expand Down
15 changes: 14 additions & 1 deletion lib/rule-list-legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
SEVERITY_TYPE,
} from './types.js';
import { RULE_TYPE_MESSAGES_LEGEND, RULE_TYPES } from './rule-type.js';
import { ConfigFormat, configNameToDisplay } from './config-format.js';

export const SEVERITY_TYPE_TO_WORD: {
[key in SEVERITY_TYPE]: string;
Expand All @@ -40,6 +41,7 @@ const LEGENDS: {
plugin: Plugin;
configsToRules: ConfigsToRules;
configEmojis: ConfigEmojis;
configFormat: ConfigFormat;
pluginPrefix: string;
ignoreConfig: readonly string[];
urlConfigs?: string;
Expand Down Expand Up @@ -178,13 +180,15 @@ function getLegendsForIndividualConfigs({
plugin,
configsToRules,
configEmojis,
configFormat,
pluginPrefix,
urlConfigs,
ignoreConfig,
}: {
plugin: Plugin;
configsToRules: ConfigsToRules;
configEmojis: ConfigEmojis;
configFormat: ConfigFormat;
pluginPrefix: string;
ignoreConfig: readonly string[];
urlConfigs?: string;
Expand Down Expand Up @@ -215,7 +219,13 @@ function getLegendsForIndividualConfigs({
return [];
}

return [`${emoji} Set in the \`${configName}\` ${configLinkOrWord}.`];
return [
`${emoji} Set in the \`${configNameToDisplay(
configName,
configFormat,
pluginPrefix
)}\` ${configLinkOrWord}.`,
];
});
}

Expand All @@ -224,6 +234,7 @@ export function generateLegend(
plugin: Plugin,
configsToRules: ConfigsToRules,
configEmojis: ConfigEmojis,
configFormat: ConfigFormat,
pluginPrefix: string,
ignoreConfig: readonly string[],
urlConfigs?: string
Expand All @@ -245,6 +256,7 @@ export function generateLegend(
plugin,
configsToRules,
configEmojis,
configFormat,
pluginPrefix,
urlConfigs,
ignoreConfig,
Expand All @@ -258,6 +270,7 @@ export function generateLegend(
plugin,
configsToRules,
configEmojis,
configFormat,
pluginPrefix,
urlConfigs,
ignoreConfig,
Expand Down
3 changes: 3 additions & 0 deletions lib/rule-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { noCase } from 'no-case';
import { getProperty } from 'dot-prop';
import { boolean, isBooleanable } from 'boolean';
import Ajv from 'ajv';
import { ConfigFormat } from './config-format.js';

function isBooleanableTrue(value: unknown): boolean {
return isBooleanable(value) && boolean(value);
Expand Down Expand Up @@ -382,6 +383,7 @@ export function updateRulesList(
pathRuleList: string,
pathPlugin: string,
configEmojis: ConfigEmojis,
configFormat: ConfigFormat,
ignoreConfig: readonly string[],
ruleListColumns: readonly COLUMN_TYPE[],
ruleListSplit: readonly string[] | RuleListSplitFunction,
Expand Down Expand Up @@ -445,6 +447,7 @@ export function updateRulesList(
plugin,
configsToRules,
configEmojis,
configFormat,
pluginPrefix,
ignoreConfig,
urlConfigs
Expand Down
4 changes: 4 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { RuleDocTitleFormat } from './rule-doc-title-format.js';
import type { TSESLint } from '@typescript-eslint/utils';
import { ConfigFormat } from './config-format.js';

// Standard ESLint types.

Expand Down Expand Up @@ -96,6 +97,7 @@ export enum COLUMN_TYPE {
export enum OPTION_TYPE {
CHECK = 'check',
CONFIG_EMOJI = 'configEmoji',
CONFIG_FORMAT = 'configFormat',
IGNORE_CONFIG = 'ignoreConfig',
IGNORE_DEPRECATED_RULES = 'ignoreDeprecatedRules',
INIT_RULE_DOCS = 'initRuleDocs',
Expand Down Expand Up @@ -139,6 +141,8 @@ export type GenerateOptions = {
| [configName: string, emoji: string]
| [configName: string]
)[];
/** The format to use for config names. Default: `name`. */
readonly configFormat?: ConfigFormat;
/** Configs to ignore from being displayed. Often used for an `all` config. */
readonly ignoreConfig?: readonly string[];
/** Whether to ignore deprecated rules from being checked, displayed, or updated. Default: `false`. */
Expand Down
3 changes: 3 additions & 0 deletions test/lib/__snapshots__/cli-test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ exports[`cli all CLI options and all config files options merges correctly, with
"🚲",
],
],
"configFormat": "plugin-colon-prefix-name",
"ignoreConfig": [
"ignoredConfigFromConfigFile1",
"ignoredConfigFromConfigFile2",
Expand Down Expand Up @@ -72,6 +73,7 @@ exports[`cli all CLI options, no config file options is called correctly 1`] = `
"🚲",
],
],
"configFormat": "plugin-colon-prefix-name",
"ignoreConfig": [
"ignoredConfigFromCli1",
"ignoredConfigFromCli2",
Expand Down Expand Up @@ -118,6 +120,7 @@ exports[`cli all config files options, no CLI options is called correctly 1`] =
"🚲",
],
],
"configFormat": "name",
"ignoreConfig": [
"ignoredConfigFromConfigFile1",
"ignoredConfigFromConfigFile2",
Expand Down

0 comments on commit c0c94c5

Please sign in to comment.