Skip to content

Commit

Permalink
feat: add --init-emojis option to suggest emojis for configs
Browse files Browse the repository at this point in the history
  • Loading branch information
bmish committed Mar 17, 2023
1 parent 0dce68f commit 00c62f8
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 32 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ There's also a `postprocess` option that's only available via a [config file](#c
| `--config-format` | The format to use for config names. See choices in below [table](#--config-format). | `name` |
| `--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. | `false` |
| `--init-emojis` | Whether to suggest an emoji for each config. Use `--config-emoji` option to utilize a suggestion. | `false` |
| `--init-rule-docs` | Whether to create rule doc files if they don't yet exist. | `false` |
| `--path-rule-doc` | Path to markdown file for each rule doc. Use `{name}` placeholder for the rule name. | `docs/rules/{name}.md` |
| `--path-rule-list` | Path to markdown file where the rules table list should live. Option can be repeated. | `README.md` |
Expand Down
27 changes: 16 additions & 11 deletions lib/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ async function loadConfigFileOptions(): Promise<GenerateOptions> {
configFormat: { type: 'string' },
ignoreConfig: schemaStringArray,
ignoreDeprecatedRules: { type: 'boolean' },
initEmojis: { type: 'boolean' },
initRuleDocs: { type: 'boolean' },
pathRuleDoc: { type: 'string' },
pathRuleList: { anyOf: [{ type: 'string' }, schemaStringArray] },
Expand All @@ -112,17 +113,17 @@ async function loadConfigFileOptions(): Promise<GenerateOptions> {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
typeof explorerResults.config.ruleListSplit === 'function'
? {
/* Functions are allowed but JSON Schema can't validate them so no-op in this case. */
}
/* Functions are allowed but JSON Schema can't validate them so no-op in this case. */
}
: { anyOf: [{ type: 'string' }, schemaStringArray] },
urlConfigs: { type: 'string' },
urlRuleDoc:
/* istanbul ignore next -- TODO: haven't tested JavaScript config files yet https://github.com/bmish/eslint-doc-generator/issues/366 */
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
typeof explorerResults.config.urlRuleDoc === 'function'
? {
/* Functions are allowed but JSON Schema can't validate them so no-op in this case. */
}
/* Functions are allowed but JSON Schema can't validate them so no-op in this case. */
}
: { type: 'string' },
};
const schema = {
Expand All @@ -139,7 +140,7 @@ async function loadConfigFileOptions(): Promise<GenerateOptions> {
validate.errors
? ajv.errorsText(validate.errors, { dataVar: 'config file' })
: /* istanbul ignore next -- this shouldn't happen */
'Invalid config file'
'Invalid config file'
);
}

Expand Down Expand Up @@ -199,8 +200,7 @@ export async function run(
.addOption(
new Option(
'--config-format <config-format>',
`(optional) The format to use for the config name. (default: ${
OPTION_DEFAULTS[OPTION_TYPE.CONFIG_FORMAT]
`(optional) The format to use for the config name. (default: ${OPTION_DEFAULTS[OPTION_TYPE.CONFIG_FORMAT]
})`
).choices(CONFIG_FORMATS)
)
Expand All @@ -217,6 +217,13 @@ export async function run(
)})`,
parseBoolean
)
.option(
'--init-emojis [boolean]',
`(optional) Whether to suggest an emoji for each config. Use \`--config-emoji\` option to utilize a suggestion. (default: ${String(
OPTION_DEFAULTS[OPTION_TYPE.INIT_EMOJIS]
)})`,
parseBoolean
)
.option(
'--init-rule-docs [boolean]',
`(optional) Whether to create rule doc files if they don't yet exist. (default: ${String(
Expand All @@ -226,8 +233,7 @@ export async function run(
)
.option(
'--path-rule-doc <path>',
`(optional) Path to markdown file for each rule doc. Use \`{name}\` placeholder for the rule name. (default: ${
OPTION_DEFAULTS[OPTION_TYPE.PATH_RULE_DOC]
`(optional) Path to markdown file for each rule doc. Use \`{name}\` placeholder for the rule name. (default: ${OPTION_DEFAULTS[OPTION_TYPE.PATH_RULE_DOC]
})`
)
.option(
Expand Down Expand Up @@ -270,8 +276,7 @@ export async function run(
.addOption(
new Option(
'--rule-doc-title-format <format>',
`(optional) The format to use for rule doc titles. (default: ${
OPTION_DEFAULTS[OPTION_TYPE.RULE_DOC_TITLE_FORMAT]
`(optional) The format to use for rule doc titles. (default: ${OPTION_DEFAULTS[OPTION_TYPE.RULE_DOC_TITLE_FORMAT]
})`
).choices(RULE_DOC_TITLE_FORMATS)
)
Expand Down
39 changes: 25 additions & 14 deletions lib/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { diff } from 'jest-diff';
import type { GenerateOptions } from './types.js';
import { OPTION_TYPE, RuleModule } from './types.js';
import { replaceRulePlaceholder } from './rule-link.js';
import { getEmojis } from 'gpt-emoji';

function stringOrArrayWithFallback<T extends string | readonly string[]>(
stringOrArray: undefined | T,
Expand All @@ -42,8 +43,8 @@ function stringOrArrayToArrayWithFallback(
stringOrArray instanceof Array // eslint-disable-line unicorn/no-instanceof-array -- using Array.isArray() loses type information about the array.
? stringOrArray
: stringOrArray
? [stringOrArray]
: [];
? [stringOrArray]
: [];
const csvStringItem = asArray.find((item) => item.includes(','));
if (csvStringItem) {
throw new Error(
Expand Down Expand Up @@ -75,6 +76,8 @@ export async function generate(path: string, options?: GenerateOptions) {
const ignoreDeprecatedRules =
options?.ignoreDeprecatedRules ??
OPTION_DEFAULTS[OPTION_TYPE.IGNORE_DEPRECATED_RULES];
const initEmojis =
options?.initEmojis ?? OPTION_DEFAULTS[OPTION_TYPE.INIT_EMOJIS];
const initRuleDocs =
options?.initRuleDocs ?? OPTION_DEFAULTS[OPTION_TYPE.INIT_RULE_DOCS];
const pathRuleDoc =
Expand Down Expand Up @@ -105,9 +108,9 @@ export async function generate(path: string, options?: GenerateOptions) {
typeof options?.ruleListSplit === 'function'
? options.ruleListSplit
: stringOrArrayToArrayWithFallback(
options?.ruleListSplit,
OPTION_DEFAULTS[OPTION_TYPE.RULE_LIST_SPLIT]
);
options?.ruleListSplit,
OPTION_DEFAULTS[OPTION_TYPE.RULE_LIST_SPLIT]
);
const urlConfigs =
options?.urlConfigs ?? OPTION_DEFAULTS[OPTION_TYPE.URL_CONFIGS];
const urlRuleDoc =
Expand All @@ -121,15 +124,15 @@ export async function generate(path: string, options?: GenerateOptions) {
const ruleModuleAsObject: RuleModule =
typeof ruleModule === 'function'
? {
// Deprecated function-style rule don't support most of the properties that object-style rules support, so we'll just use the bare minimum.
meta: {
// @ts-expect-error -- type is missing for this property
schema: ruleModule.schema, // eslint-disable-line @typescript-eslint/no-unsafe-assignment -- type is missing for this property
// @ts-expect-error -- type is missing for this property
deprecated: ruleModule.deprecated, // eslint-disable-line @typescript-eslint/no-unsafe-assignment -- type is missing for this property
},
create: ruleModule,
}
// Deprecated function-style rule don't support most of the properties that object-style rules support, so we'll just use the bare minimum.
meta: {
// @ts-expect-error -- type is missing for this property
schema: ruleModule.schema, // eslint-disable-line @typescript-eslint/no-unsafe-assignment -- type is missing for this property
// @ts-expect-error -- type is missing for this property
deprecated: ruleModule.deprecated, // eslint-disable-line @typescript-eslint/no-unsafe-assignment -- type is missing for this property
},
create: ruleModule,
}
: ruleModule;
const tuple: [string, RuleModule] = [name, ruleModuleAsObject];
return tuple;
Expand Down Expand Up @@ -246,6 +249,14 @@ export async function generate(path: string, options?: GenerateOptions) {
);
}

if (initEmojis) {
for (const config of Object.keys(plugin.configs || {})) {
// TODO: show a nice table of output
const result = await getEmojis(config, 1);
console.log(config, result[0]);
}
}

for (const pathRuleListItem of pathRuleList) {
// Find the exact filename.
const pathToFile = getPathWithExactFileNameCasing(
Expand Down
1 change: 1 addition & 0 deletions lib/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const OPTION_DEFAULTS = {
[OPTION_TYPE.CONFIG_FORMAT]: DEFAULT_CONFIG_FORMAT,
[OPTION_TYPE.IGNORE_CONFIG]: [],
[OPTION_TYPE.IGNORE_DEPRECATED_RULES]: false,
[OPTION_TYPE.INIT_EMOJIS]: false,
[OPTION_TYPE.INIT_RULE_DOCS]: false,
[OPTION_TYPE.PATH_RULE_DOC]: join('docs', 'rules', '{name}.md'),
[OPTION_TYPE.PATH_RULE_LIST]: ['README.md'],
Expand Down
2 changes: 0 additions & 2 deletions lib/package-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ export async function loadPlugin(path: string): Promise<Plugin> {
const propertiesToCheck: readonly (keyof PackageJson.ExportConditions)[] =
['.', 'node', 'import', 'require', 'default'];
for (const prop of propertiesToCheck) {
// @ts-expect-error -- The union type for the object is causing trouble.
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const value = exports[prop];
if (typeof value === 'string') {
pluginEntryPoint = value;
Expand Down
3 changes: 3 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export enum OPTION_TYPE {
CONFIG_FORMAT = 'configFormat',
IGNORE_CONFIG = 'ignoreConfig',
IGNORE_DEPRECATED_RULES = 'ignoreDeprecatedRules',
INIT_EMOJIS = 'initEmojis',
INIT_RULE_DOCS = 'initRuleDocs',
PATH_RULE_DOC = 'pathRuleDoc',
PATH_RULE_LIST = 'pathRuleList',
Expand Down Expand Up @@ -164,6 +165,8 @@ export type GenerateOptions = {
readonly ignoreConfig?: readonly string[];
/** Whether to ignore deprecated rules from being checked, displayed, or updated. Default: `false`. */
readonly ignoreDeprecatedRules?: boolean;
/** Whether to suggest an emoji for each config. Use `--config-emoji` option to utilize a suggestion. Default: `false`. */
readonly initEmojis?: boolean;
/** Whether to create rule doc files if they don't yet exist. Default: `false`. */
readonly initRuleDocs?: boolean;
/** Path to markdown file for each rule doc. Use `{name}` placeholder for the rule name. Default: `docs/rules/{name}.md`. */
Expand Down
Loading

0 comments on commit 00c62f8

Please sign in to comment.