Skip to content
This repository was archived by the owner on Mar 7, 2025. It is now read-only.

Commit 746fcae

Browse files
authored
Minor generation script improvements (#136)
1 parent 89dd6d8 commit 746fcae

File tree

8 files changed

+65
-61
lines changed

8 files changed

+65
-61
lines changed

scripts/generate-rule-files/index.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ import dedent from 'ts-dedent';
77
import type { Plugin } from './contracts';
88
import { format } from './src/format';
99
import { JsDocBuilder } from './src/js-doc-builder';
10-
import { pluginsMap } from './src/plugins-map';
10+
import { PLUGIN_REGISTRY } from './src/plugins-map';
1111
import { RuleFile } from './src/rule-file';
1212

1313
/**
14-
* Generate the index.d.ts file for the plugin's rules that will re-export all
15-
* rules.
14+
* Generate the `index.d.ts` file for the plugin's rules that will re-export all rules.
1615
*/
1716
function generateRuleIndexFile(
1817
pluginDirectory: string,
@@ -24,14 +23,14 @@ function generateRuleIndexFile(
2423
);
2524

2625
/**
27-
* Build all the import statements for the rules
26+
* Build all the import statements for the rules.
2827
*/
2928
const rulesImports: string = generatedRules
3029
.map((name) => `import type { ${pascalCase(name)}Rule } from './${name}';`)
3130
.join('\n');
3231

3332
/**
34-
* Build the exported type that is an intersection of all the rules
33+
* Build the exported type that is an intersection of all the rules.
3534
*/
3635
const rulesFinalIntersection: string = generatedRules
3736
.map((name) => `${pascalCase(name)}Rule`)
@@ -43,7 +42,7 @@ function generateRuleIndexFile(
4342
`);
4443

4544
/**
46-
* Write the final index.d.ts file
45+
* Write the final `index.d.ts` file.
4746
*/
4847
const fileContent: string = dedent(`
4948
${rulesImports}
@@ -56,7 +55,7 @@ function generateRuleIndexFile(
5655
}
5756

5857
/**
59-
* Print a report after having generated rules files for a plugin
58+
* Print a report after having generated rules files for a plugin.
6059
*/
6160
function printGenerationReport(
6261
rules: [string, Rule.RuleModule][],
@@ -75,7 +74,7 @@ function printGenerationReport(
7574
}
7675

7776
/**
78-
* Generate a .d.ts file for each rule in the given plugin
77+
* Generate a `.d.ts` file for each rule in the given plugin.
7978
*/
8079
async function generateRulesFiles(
8180
plugin: Plugin,
@@ -106,8 +105,7 @@ async function generateRulesFiles(
106105
return { failedRules };
107106
}
108107
/**
109-
* If it doesn't exist, create the directory that will contain the plugin's
110-
* rule files.
108+
* If it doesn't exist, create the directory that will contain the plugin's rule files.
111109
*/
112110
function createPluginDirectory(
113111
pluginName: string,
@@ -124,27 +122,28 @@ function createPluginDirectory(
124122
}
125123

126124
mkdirSync(pluginDirectory, { mode: 0o755, recursive: true });
125+
127126
return pluginDirectory;
128127
}
129128

130-
export async function run(
131-
options: {
132-
plugins?: string[];
133-
targetDirectory?: string;
134-
} = {},
135-
): Promise<void> {
129+
export interface RunOptions {
130+
plugins?: string[];
131+
targetDirectory?: string;
132+
}
133+
134+
export async function run(options: RunOptions = {}): Promise<void> {
136135
const { plugins, targetDirectory } = options;
137136

138-
const wantedPlugins: string[] = plugins ?? Object.keys(pluginsMap);
137+
const wantedPlugins: string[] = plugins ?? Object.keys(PLUGIN_REGISTRY);
139138

140139
for (const pluginName of wantedPlugins) {
141-
const plugin: Plugin = pluginsMap[pluginName]!;
140+
const plugin: Plugin = PLUGIN_REGISTRY[pluginName]!;
142141

143142
if (!plugin) {
144-
throw new Error(`Plugin ${pluginName} doesn't exist`);
143+
throw new Error(`Plugin ${pluginName} doesn't exist.`);
145144
}
146145

147-
logger.info(`Generating ${plugin.name} rules`);
146+
logger.info(`Generating ${plugin.name} rules.`);
148147

149148
const pluginDir: string = createPluginDirectory(
150149
pluginName,

scripts/generate-rule-files/src/format.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Options } from 'prettier';
22
import { format as prettierFormat } from 'prettier';
33

44
/**
5-
* Our custom prettier configuration
5+
* Our custom prettier configuration.
66
*/
77
const PRETTIER_OPTIONS: Options = {
88
plugins: [require.resolve('prettier-plugin-organize-imports')],

scripts/generate-rule-files/src/js-doc-builder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/**
2-
* Simple class helper to build a JSDoc comment
2+
* Simple class helper to build a JSDoc comment.
33
*/
44
export class JsDocBuilder {
55
private readonly content: string[] = [];
66

7-
static build(): JsDocBuilder {
7+
public static build(): JsDocBuilder {
88
return new JsDocBuilder();
99
}
1010

scripts/generate-rule-files/src/json-schema-to-ts.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ import type { JSONSchema4 } from 'json-schema';
22
import { compile } from 'json-schema-to-typescript';
33

44
/**
5-
* Remove some comments that are generated by json-schema-to-typescript
6-
* and that we don't need
5+
* Remove unnecessary comments that are generated by `json-schema-to-typescript`.
76
*/
8-
function removeGarbageFromJsDocs(content: string): string {
7+
function cleanJsDoc(content: string): string {
98
const patterns: RegExp[] = [
109
/\* This interface was referenced by .+ JSON-Schema definition/,
1110
/\* via the `.+` "/,
@@ -18,7 +17,7 @@ function removeGarbageFromJsDocs(content: string): string {
1817
}
1918

2019
/**
21-
* Generate a type from the given JSON schema
20+
* Generate a type from the given JSON schema.
2221
*/
2322
export async function generateTypeFromSchema(
2423
schema: JSONSchema4,
@@ -27,9 +26,12 @@ export async function generateTypeFromSchema(
2726
const result: string = await compile(schema, typeName, {
2827
format: false,
2928
bannerComment: '',
30-
style: { singleQuote: true, trailingComma: 'all' },
29+
style: {
30+
singleQuote: true,
31+
trailingComma: 'all',
32+
},
3133
unknownAny: false,
3234
});
3335

34-
return removeGarbageFromJsDocs(result);
36+
return cleanJsDoc(result);
3537
}

scripts/generate-rule-files/src/plugins-map.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import type { Plugin } from '../contracts';
2525
/**
2626
* Map of plugins for which the script will generate rule files.
2727
*/
28-
export const pluginsMap: Record<string, Plugin> = {
28+
export const PLUGIN_REGISTRY: Readonly<Record<string, Plugin>> = {
2929
eslint: {
3030
name: 'Eslint',
3131
rules: Object.fromEntries(new eslint.Linter().getRules().entries()),
@@ -77,4 +77,4 @@ export const pluginsMap: Record<string, Plugin> = {
7777
name: 'VuePug',
7878
rules: (eslintPluginVuePug as Plugin).rules,
7979
},
80-
};
80+
} as const;

scripts/generate-rule-files/src/rule-file.ts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { generateTypeFromSchema } from './json-schema-to-ts';
1111

1212
export class RuleFile {
1313
private content: string = '';
14+
1415
private readonly rulePath: string;
1516
private readonly ruleNamePascalCase: string;
1617

@@ -19,7 +20,7 @@ export class RuleFile {
1920
private sideSchema?: JSONSchema4;
2021
private thirdSchema?: JSONSchema4;
2122

22-
constructor(
23+
public constructor(
2324
private readonly plugin: Plugin,
2425
pluginDirectory: string,
2526
private readonly ruleName: string,
@@ -43,17 +44,18 @@ export class RuleFile {
4344
}
4445

4546
/**
46-
* Append the `import type { RuleConfig } at the top of the file
47+
* Append the `import type { RuleConfig } from '../rule-config'` at the top of the file.
4748
*/
4849
public appendRuleConfigImport(): void {
4950
const nestedDepth: number = this.ruleName.split('/').length;
50-
const ruleConfigImportPath: string =
51-
'../'.repeat(nestedDepth) + 'rule-config';
51+
const ruleConfigImportPath: string = `${'../'.repeat(
52+
nestedDepth,
53+
)}rule-config`;
5254
this.content += `import type { RuleConfig } from '${ruleConfigImportPath}'\n\n`;
5355
}
5456

5557
/**
56-
* Build the rule description to append to the JSDoc
58+
* Build the rule description to append to the JSDoc.
5759
*/
5860
public buildDescription(): string {
5961
let description: string = upperCaseFirst(
@@ -68,7 +70,7 @@ export class RuleFile {
6870
}
6971

7072
/**
71-
* Build the `@see` url to the rule documentation to append to the JSDoc
73+
* Build the `@see` url to the rule documentation to append to the JSDoc.
7274
*/
7375
public buildSeeDocLink(): string {
7476
const { meta } = this.rule;
@@ -80,7 +82,7 @@ export class RuleFile {
8082
}
8183

8284
/**
83-
* Generate a JSDoc with the rule description and `@see` url
85+
* Generate a JSDoc with the rule description and `@see` url.
8486
*/
8587
public generateTypeJsDoc(): string {
8688
return JsDocBuilder.build()
@@ -93,7 +95,7 @@ export class RuleFile {
9395
}
9496

9597
/**
96-
* Generate a type from a JSON schema and append it to the file content
98+
* Generate a type from a JSON schema and append it to the file content.
9799
*/
98100
private async appendJsonSchemaType(
99101
schema: JSONSchema4,
@@ -110,7 +112,7 @@ export class RuleFile {
110112
}
111113

112114
/**
113-
* Generate and append types for the rule schemas
115+
* Generate and append types for the rule schemas.
114116
*/
115117
private async appendRuleSchemaTypes(): Promise<void> {
116118
if (this.thirdSchema) {
@@ -127,7 +129,7 @@ export class RuleFile {
127129
}
128130

129131
/**
130-
* Append the rule type options to the file content
132+
* Append the rule type options to the file content.
131133
*/
132134
private appendRuleOptions(): void {
133135
const ruleName: string = this.ruleNamePascalCase;
@@ -148,7 +150,7 @@ export class RuleFile {
148150
}
149151

150152
/**
151-
* Append the rule config type to the file content
153+
* Append the rule config type to the file content.
152154
*/
153155
private appendRuleConfig(): void {
154156
const ruleName: string = this.ruleNamePascalCase;
@@ -161,7 +163,7 @@ export class RuleFile {
161163
}
162164

163165
/**
164-
* Append the final rule interface to the file content
166+
* Append the final rule interface to the file content.
165167
*/
166168
private appendRule(): void {
167169
const ruleName: string = this.ruleNamePascalCase;
@@ -180,7 +182,7 @@ export class RuleFile {
180182
}
181183

182184
/**
183-
* Create the directory of the rule file if it doesn't exist
185+
* Create the directory of the rule file if it doesn't exist.
184186
*/
185187
private createRuleDirectory(): void {
186188
const subPath: string = dirname(this.rulePath.toLowerCase());
@@ -190,7 +192,7 @@ export class RuleFile {
190192
}
191193

192194
/**
193-
* Generate a file with the rule typings
195+
* Generate a file with the rule typings.
194196
*/
195197
public async generate(): Promise<string> {
196198
this.appendRuleConfigImport();
@@ -209,10 +211,11 @@ export class RuleFile {
209211
}
210212

211213
/**
212-
* Must be called after `generate()` to write the file
214+
* Must be called after `generate()` to write the file.
213215
*/
214216
public writeGeneratedContent(): void {
215217
this.createRuleDirectory();
218+
216219
writeFileSync(this.rulePath, this.content);
217220
}
218221
}

tests/__snapshots__/generate-rule-files.test.ts.snap

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,9 @@ export interface MyRuleRule {
7474
"
7575
`;
7676
77-
exports[`Rule File > Three schemas 1`] = `
77+
exports[`Rule File > Side schemas 1`] = `
7878
"import type { RuleConfig } from '../rule-config';
7979
80-
/**
81-
* Setting.
82-
*/
83-
export type MyRuleSetting = boolean;
84-
8580
/**
8681
* Config.
8782
*/
@@ -95,7 +90,7 @@ export type MyRuleOption = number;
9590
/**
9691
* Options.
9792
*/
98-
export type MyRuleOptions = [MyRuleOption?, MyRuleConfig?, MyRuleSetting?];
93+
export type MyRuleOptions = [MyRuleOption?, MyRuleConfig?];
9994
10095
/**
10196
* My rule description.
@@ -120,9 +115,14 @@ export interface MyRuleRule {
120115
"
121116
`;
122117
123-
exports[`Rule File > Two schemas 1`] = `
118+
exports[`Rule File > Third schemas 1`] = `
124119
"import type { RuleConfig } from '../rule-config';
125120
121+
/**
122+
* Setting.
123+
*/
124+
export type MyRuleSetting = boolean;
125+
126126
/**
127127
* Config.
128128
*/
@@ -136,7 +136,7 @@ export type MyRuleOption = number;
136136
/**
137137
* Options.
138138
*/
139-
export type MyRuleOptions = [MyRuleOption?, MyRuleConfig?];
139+
export type MyRuleOptions = [MyRuleOption?, MyRuleConfig?, MyRuleSetting?];
140140
141141
/**
142142
* My rule description.

0 commit comments

Comments
 (0)