/
init-generator.ts
147 lines (130 loc) · 4.79 KB
/
init-generator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import { blue, yellow } from "colorette";
import path from "path";
import * as Question from "./utils/scaffold-utils";
import { CustomGenerator } from "./types";
import { existsSync, mkdirSync } from "fs";
import handlers from "./handlers";
import { readFileSync, writeFileSync } from "fs";
/**
*
* Generator for initializing a webpack config
*
* @class InitGenerator
* @extends CustomGenerator
* @returns {Void} After execution, transforms are triggered
*
*/
export default class InitGenerator extends CustomGenerator {
public template: string;
public generationPath: string;
public resolvedGenerationPath: string;
public configurationPath: string;
public supportedTemplates: string[];
public answers: Record<string, unknown>;
public force: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public utils: any;
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
public constructor(args: any, opts: any) {
super(args, opts);
const { options } = opts;
this.template = options.template;
this.generationPath = options.generationPath;
this.resolvedGenerationPath = path.resolve(process.cwd(), this.generationPath);
this.force = options.force;
this.dependencies = ["webpack", "webpack-cli"];
this.supportedTemplates = Object.keys(handlers);
this.answers = {};
const { cli } = opts;
this.utils = cli.utils;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public async prompting(): Promise<void | any> {
if (!existsSync(this.resolvedGenerationPath)) {
this.utils.logger.log(
`${blue(
"ℹ INFO ",
)} supplied generation path doesn't exist, required folders will be created.`,
);
try {
mkdirSync(this.resolvedGenerationPath, { recursive: true });
} catch (error) {
this.utils.logger.error(`Failed to create directory.\n ${error}`);
process.exit(2);
}
}
if (!this.supportedTemplates.includes(this.template)) {
this.utils.logger.warn(
`⚠ ${this.template} is not a valid template, please select one from below`,
);
const { selectedTemplate } = await Question.List(
this,
"selectedTemplate",
"Select a valid template from below:",
this.supportedTemplates,
"default",
false,
);
this.template = selectedTemplate;
}
await handlers[this.template].questions(this, Question);
// Handle installation of prettier
try {
// eslint-disable-next-line node/no-extraneous-require
require.resolve("prettier");
} catch (err) {
const { installPrettier } = await Question.Confirm(
this,
"installPrettier",
"Do you like to install prettier to format generated configuration?",
true,
false,
);
if (installPrettier) {
this.dependencies.push("prettier");
}
}
}
public async installPlugins(): Promise<void> {
const { packager } = await Question.List(
this,
"packager",
"Pick a package manager:",
this.utils.getAvailableInstallers(),
"npm",
false,
);
const opts: {
dev?: boolean;
"save-dev"?: boolean;
} = packager === "yarn" ? { dev: true } : { "save-dev": true };
this.scheduleInstallTask(packager, this.dependencies, opts, {
cwd: this.generationPath,
});
}
public writing(): void {
this.utils.logger.log(`${blue("ℹ INFO ")} Initialising project...`);
handlers[this.template].generate(this);
}
public end(): void {
// Prettify configuration file if possible
try {
// eslint-disable-next-line node/no-extraneous-require, @typescript-eslint/no-var-requires
const prettier = require("prettier");
const source = readFileSync(this.configurationPath, {
encoding: "utf8",
});
const formattedSource = prettier.format(source, {
parser: "babel",
});
writeFileSync(this.configurationPath, formattedSource);
} catch (err) {
this.utils.logger.log(
`${yellow(
`⚠ Generated configuration may not be properly formatted as prettier is not installed.`,
)}`,
);
return;
}
}
}