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 --url-rule-doc #262

Merged
merged 1 commit into from
Nov 21, 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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ There's also an optional path argument if you need to point the CLI to an ESLint
| `--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. |
| `--url-rule-doc` | Link to documentation for each rule. Useful when it differs from the rule doc path on disk (e.g. custom documentation site in use). Use `{name}` placeholder for the rule name. |

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

Expand Down
5 changes: 5 additions & 0 deletions lib/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ async function loadConfigFileOptions() {
ruleListColumns: { type: 'string' },
splitBy: { type: 'string' },
urlConfigs: { type: 'string' },
urlRuleDoc: { type: 'string' },
};
const schema = {
type: 'object',
Expand Down Expand Up @@ -204,6 +205,10 @@ export async function run(
'--url-configs <url>',
'(optional) Link to documentation about the ESLint configurations exported by the plugin.'
)
.option(
'--url-rule-doc <url>',
'(optional) Link to documentation for each rule. Useful when it differs from the rule doc path on disk (e.g. custom documentation site in use). Use `{name}` placeholder for the rule name.'
)
.action(async function (path, options: GenerateOptions) {
// Load config file options and merge with CLI options.
// CLI options take precedence.
Expand Down
6 changes: 5 additions & 1 deletion 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) {
const splitBy = options?.splitBy ?? OPTION_DEFAULTS[OPTION_TYPE.SPLIT_BY];
const urlConfigs =
options?.urlConfigs ?? OPTION_DEFAULTS[OPTION_TYPE.URL_CONFIGS];
const urlRuleDoc =
options?.urlRuleDoc ?? OPTION_DEFAULTS[OPTION_TYPE.URL_RULE_DOC];

// Gather details about rules.
const details: RuleDetails[] = Object.entries(plugin.rules)
Expand Down Expand Up @@ -188,7 +190,8 @@ export async function generate(path: string, options?: GenerateOptions) {
ignoreConfig,
ruleDocNotices,
ruleDocTitleFormat,
urlConfigs
urlConfigs,
urlRuleDoc
);

const contents = readFileSync(pathToDoc).toString();
Expand Down Expand Up @@ -260,6 +263,7 @@ export async function generate(path: string, options?: GenerateOptions) {
ignoreConfig,
ruleListColumns,
urlConfigs,
urlRuleDoc,
splitBy
);

Expand Down
3 changes: 3 additions & 0 deletions lib/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export enum OPTION_TYPE {
RULE_LIST_COLUMNS = 'ruleListColumns',
SPLIT_BY = 'splitBy',
URL_CONFIGS = 'urlConfigs',
URL_RULE_DOC = 'urlRuleDoc',
}

const DEFAULT_RULE_DOC_TITLE_FORMAT: RuleDocTitleFormat =
Expand Down Expand Up @@ -82,6 +83,7 @@ export const OPTION_DEFAULTS = {
.join(','),
[OPTION_TYPE.SPLIT_BY]: undefined,
[OPTION_TYPE.URL_CONFIGS]: undefined,
[OPTION_TYPE.URL_RULE_DOC]: undefined,
// eslint-disable-next-line prettier/prettier -- TODO: waiting on prettier support for TypeScript 4.9: https://github.com/prettier/prettier/issues/13516.
} satisfies Record<OPTION_TYPE, unknown>; // Satisfies is used to ensure all options are included, but without losing type information.

Expand All @@ -101,4 +103,5 @@ export type GenerateOptions = {
ruleListColumns?: string;
splitBy?: string;
urlConfigs?: string;
urlRuleDoc?: string;
};
27 changes: 18 additions & 9 deletions lib/rule-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ function buildRuleRow(
pluginPrefix: string,
pathRuleDoc: string,
configEmojis: ConfigEmojis,
ignoreConfig: string[]
ignoreConfig: string[],
urlRuleDoc?: string
): string[] {
const columns: {
[key in COLUMN_TYPE]: string;
Expand Down Expand Up @@ -164,7 +165,7 @@ function buildRuleRow(
[COLUMN_TYPE.HAS_SUGGESTIONS]: rule.hasSuggestions
? EMOJI_HAS_SUGGESTIONS
: '',
[COLUMN_TYPE.NAME]: `[${rule.name}](${pathRuleDoc.replace(
[COLUMN_TYPE.NAME]: `[${rule.name}](${(urlRuleDoc ?? pathRuleDoc).replace(
/{name}/g,
rule.name
)})`,
Expand All @@ -190,7 +191,8 @@ function generateRulesListMarkdown(
pluginPrefix: string,
pathRuleDoc: string,
configEmojis: ConfigEmojis,
ignoreConfig: string[]
ignoreConfig: string[],
urlRuleDoc?: string
): string {
const listHeaderRow = (
Object.entries(columns) as [COLUMN_TYPE, boolean][]
Expand Down Expand Up @@ -221,7 +223,8 @@ function generateRulesListMarkdown(
pluginPrefix,
pathRuleDoc,
configEmojis,
ignoreConfig
ignoreConfig,
urlRuleDoc
)
),
],
Expand All @@ -241,7 +244,8 @@ function generateRulesListMarkdownWithSplitBy(
pathRuleDoc: string,
configEmojis: ConfigEmojis,
ignoreConfig: string[],
splitBy: string
splitBy: string,
urlRuleDoc?: string
): string {
const values = new Set(
details.map((detail) => getPropertyFromRule(plugin, detail.name, splitBy))
Expand Down Expand Up @@ -278,7 +282,8 @@ function generateRulesListMarkdownWithSplitBy(
pluginPrefix,
pathRuleDoc,
configEmojis,
ignoreConfig
ignoreConfig,
urlRuleDoc
)
);
}
Expand Down Expand Up @@ -309,7 +314,8 @@ function generateRulesListMarkdownWithSplitBy(
pluginPrefix,
pathRuleDoc,
configEmojis,
ignoreConfig
ignoreConfig,
urlRuleDoc
)
);
}
Expand All @@ -330,6 +336,7 @@ export function updateRulesList(
ignoreConfig: string[],
ruleListColumns: COLUMN_TYPE[],
urlConfigs?: string,
urlRuleDoc?: string,
splitBy?: string
): string {
let listStartIndex = markdown.indexOf(BEGIN_RULE_LIST_MARKER);
Expand Down Expand Up @@ -399,7 +406,8 @@ export function updateRulesList(
pathRuleDoc,
configEmojis,
ignoreConfig,
splitBy
splitBy,
urlRuleDoc
)
: generateRulesListMarkdown(
columns,
Expand All @@ -408,7 +416,8 @@ export function updateRulesList(
pluginPrefix,
pathRuleDoc,
configEmojis,
ignoreConfig
ignoreConfig,
urlRuleDoc
);

const newContent = `${legend ? `${legend}\n\n` : ''}${list}`;
Expand Down
30 changes: 22 additions & 8 deletions lib/rule-notices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const RULE_NOTICES: {
replacedBy: readonly string[] | undefined;
pluginPrefix: string;
type?: RULE_TYPE;
urlRuleDoc?: string;
}) => string);
} = {
// Configs notice varies based on whether the rule is configured in one or more configs.
Expand Down Expand Up @@ -152,7 +153,12 @@ const RULE_NOTICES: {
},

// Deprecated notice has optional "replaced by" rules list.
[NOTICE_TYPE.DEPRECATED]: ({ replacedBy, pluginPrefix, ruleName }) => {
[NOTICE_TYPE.DEPRECATED]: ({
replacedBy,
pluginPrefix,
ruleName,
urlRuleDoc,
}) => {
// Determine the relative path to the rule doc root so that any replacement rule links can account for this.
const slashesInCurrentRuleName = ruleName.match(/\//g);
const nestingDepthOfCurrentRule = slashesInCurrentRuleName?.length ?? 0;
Expand All @@ -163,7 +169,8 @@ const RULE_NOTICES: {
? ` It was replaced by ${ruleNamesToList(
replacedBy,
pluginPrefix,
relativePathToRuleDocRoot
relativePathToRuleDocRoot,
urlRuleDoc
)}.`
: ''
}`;
Expand Down Expand Up @@ -206,7 +213,8 @@ const RULE_NOTICES: {
function ruleNamesToList(
ruleNames: readonly string[],
pluginPrefix: string,
relativePathToRuleDocRoot: string
relativePathToRuleDocRoot: string,
urlRuleDoc?: string
) {
return ruleNames
.map((ruleName) => {
Expand All @@ -218,8 +226,10 @@ function ruleNamesToList(
? ruleName.slice(pluginPrefix.length + 1)
: ruleName;
return `[\`${ruleNameWithoutPluginPrefix}\`](${
relativePathToRuleDocRoot + ruleNameWithoutPluginPrefix
}.md)`;
urlRuleDoc
? urlRuleDoc.replace(/{name}/g, ruleName)
: `${relativePathToRuleDocRoot + ruleNameWithoutPluginPrefix}.md`
})`;
})
.join(', ');
}
Expand Down Expand Up @@ -273,7 +283,8 @@ function getRuleNoticeLines(
configEmojis: ConfigEmojis,
ignoreConfig: string[],
ruleDocNotices: NOTICE_TYPE[],
urlConfigs?: string
urlConfigs?: string,
urlRuleDoc?: string
) {
const lines: string[] = [];

Expand Down Expand Up @@ -352,6 +363,7 @@ function getRuleNoticeLines(
replacedBy: rule.meta?.replacedBy,
pluginPrefix,
type: rule.meta?.type as RULE_TYPE, // Convert union type to enum.
urlRuleDoc,
})
: ruleNoticeStrOrFn
);
Expand Down Expand Up @@ -435,7 +447,8 @@ export function generateRuleHeaderLines(
ignoreConfig: string[],
ruleDocNotices: NOTICE_TYPE[],
ruleDocTitleFormat: RuleDocTitleFormat,
urlConfigs?: string
urlConfigs?: string,
urlRuleDoc?: string
): string {
return [
makeTitle(name, description, pluginPrefix, ruleDocTitleFormat),
Expand All @@ -447,7 +460,8 @@ export function generateRuleHeaderLines(
configEmojis,
ignoreConfig,
ruleDocNotices,
urlConfigs
urlConfigs,
urlRuleDoc
),
'',
END_RULE_HEADER_MARKER,
Expand Down
9 changes: 6 additions & 3 deletions test/lib/__snapshots__/cli-test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ exports[`cli all CLI options and all config files options merges correctly, with
"ruleDocTitleFormat": "name",
"ruleListColumns": "type",
"splitBy": "meta.docs.foo-from-cli",
"urlConfigs": "www.example.com/configs-from-cli",
"urlConfigs": "https://example.com/configs-url-from-cli",
"urlRuleDoc": "https://example.com/rule-doc-url-from-cli",
},
]
`;
Expand Down Expand Up @@ -70,7 +71,8 @@ exports[`cli all CLI options, no config file options is called correctly 1`] = `
"ruleDocTitleFormat": "name",
"ruleListColumns": "type",
"splitBy": "meta.docs.foo-from-cli",
"urlConfigs": "www.example.com/configs-from-cli",
"urlConfigs": "https://example.com/configs-url-from-cli",
"urlRuleDoc": "https://example.com/rule-doc-url-from-cli",
},
]
`;
Expand Down Expand Up @@ -104,7 +106,8 @@ exports[`cli all config files options, no CLI options is called correctly 1`] =
"ruleDocTitleFormat": "desc",
"ruleListColumns": "fixable,hasSuggestions",
"splitBy": "meta.docs.foo-from-config-file",
"urlConfigs": "www.example.com/configs-from-config-file",
"urlConfigs": "https://example.com/configs-url-from-config-file",
"urlRuleDoc": "https://example.com/rule-doc-url-from-config-file",
},
]
`;
Expand Down
10 changes: 8 additions & 2 deletions test/lib/cli-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ const configFileOptionsAll: { [key in OPTION_TYPE]: unknown } = {
ruleDocTitleFormat: 'desc',
ruleListColumns: 'fixable,hasSuggestions',
splitBy: 'meta.docs.foo-from-config-file',
urlConfigs: 'www.example.com/configs-from-config-file',
urlConfigs: 'https://example.com/configs-url-from-config-file',
urlRuleDoc: 'https://example.com/rule-doc-url-from-config-file',
};

const cliOptionsAll: { [key in OPTION_TYPE]: string[] } = {
Expand Down Expand Up @@ -85,7 +86,12 @@ const cliOptionsAll: { [key in OPTION_TYPE]: string[] } = {

[OPTION_TYPE.URL_CONFIGS]: [
'--url-configs',
'www.example.com/configs-from-cli',
'https://example.com/configs-url-from-cli',
],

[OPTION_TYPE.URL_RULE_DOC]: [
'--url-rule-doc',
'https://example.com/rule-doc-url-from-cli',
],
};

Expand Down
14 changes: 7 additions & 7 deletions test/lib/generate/__snapshots__/url-configs-test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ exports[`generate (--url-configs) basic includes the config link 1`] = `
"## Rules
<!-- begin auto-generated rules list -->

💼 [Configurations](http://example.com/configs) enabled in.\\
✅ Set in the \`recommended\` [configuration](http://example.com/configs).
💼 [Configurations](https://example.com/configs) enabled in.\\
✅ Set in the \`recommended\` [configuration](https://example.com/configs).

| Name | Description | 💼 |
| :----------------------------- | :---------------------- | :---------------------- |
Expand All @@ -19,7 +19,7 @@ exports[`generate (--url-configs) basic includes the config link 1`] = `
exports[`generate (--url-configs) basic includes the config link 2`] = `
"# Description for no-foo (\`test/no-foo\`)

💼 This rule is enabled in the ✅ \`recommended\` [config](http://example.com/configs).
💼 This rule is enabled in the ✅ \`recommended\` [config](https://example.com/configs).

<!-- end auto-generated rule header -->
"
Expand All @@ -28,7 +28,7 @@ exports[`generate (--url-configs) basic includes the config link 2`] = `
exports[`generate (--url-configs) basic includes the config link 3`] = `
"# Description for no-bar (\`test/no-bar\`)

💼 This rule is enabled in the \`customConfig\` [config](http://example.com/configs).
💼 This rule is enabled in the \`customConfig\` [config](https://example.com/configs).

<!-- end auto-generated rule header -->
"
Expand All @@ -38,8 +38,8 @@ exports[`generate (--url-configs) with only recommended config includes the conf
"## Rules
<!-- begin auto-generated rules list -->

💼 [Configurations](http://example.com/configs) enabled in.\\
✅ Set in the \`recommended\` [configuration](http://example.com/configs).
💼 [Configurations](https://example.com/configs) enabled in.\\
✅ Set in the \`recommended\` [configuration](https://example.com/configs).

| Name | Description | 💼 |
| :----------------------------- | :---------------------- | :- |
Expand All @@ -52,7 +52,7 @@ exports[`generate (--url-configs) with only recommended config includes the conf
exports[`generate (--url-configs) with only recommended config includes the config link 2`] = `
"# Description for no-foo (\`test/no-foo\`)

💼 This rule is enabled in the ✅ \`recommended\` [config](http://example.com/configs).
💼 This rule is enabled in the ✅ \`recommended\` [config](https://example.com/configs).

<!-- end auto-generated rule header -->
"
Expand Down