Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new option --config-format #368

Merged
merged 1 commit into from
Dec 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 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,16 @@ 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` |
| `prefix-name` | `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
25 changes: 25 additions & 0 deletions lib/config-format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const CONFIG_FORMATS = [
'name',
'plugin-colon-prefix-name',
'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}`; // Exact format used in an ESLint config file under "extends".
case 'prefix-name':
return `${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