@robot-admin/git-standards 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +62 -0
- package/README.md +324 -0
- package/bin/robot-standards.js +64 -0
- package/dist/cli/doctor.cjs +276 -0
- package/dist/cli/doctor.cjs.map +1 -0
- package/dist/cli/doctor.d.cts +10 -0
- package/dist/cli/doctor.d.ts +10 -0
- package/dist/cli/doctor.js +241 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/init.cjs +1032 -0
- package/dist/cli/init.cjs.map +1 -0
- package/dist/cli/init.d.cts +31 -0
- package/dist/cli/init.d.ts +31 -0
- package/dist/cli/init.js +997 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/index.cjs +1280 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +86 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +1228 -0
- package/dist/index.js.map +1 -0
- package/package.json +71 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1228 @@
|
|
|
1
|
+
// src/configs/lint-staged.ts
|
|
2
|
+
function createLintStagedConfig(options = {}) {
|
|
3
|
+
const codePattern = options.filePatterns?.code || "src/**/*.{js,jsx,ts,tsx,vue}";
|
|
4
|
+
const markupPattern = options.filePatterns?.markup || "*.{json,md,yml,yaml}";
|
|
5
|
+
const codeCommands = [];
|
|
6
|
+
if (options.oxlint !== false) {
|
|
7
|
+
codeCommands.push("oxlint --max-warnings 0 --deny-warnings");
|
|
8
|
+
}
|
|
9
|
+
if (options.eslint !== false) {
|
|
10
|
+
codeCommands.push("eslint --fix --no-cache");
|
|
11
|
+
}
|
|
12
|
+
if (options.prettier !== false) {
|
|
13
|
+
codeCommands.push("prettier --write");
|
|
14
|
+
}
|
|
15
|
+
const config = {};
|
|
16
|
+
if (codeCommands.length > 0) {
|
|
17
|
+
config[codePattern] = codeCommands;
|
|
18
|
+
}
|
|
19
|
+
if (options.prettier !== false) {
|
|
20
|
+
config[markupPattern] = ["prettier --write"];
|
|
21
|
+
}
|
|
22
|
+
return config;
|
|
23
|
+
}
|
|
24
|
+
function generateLintStagedConfig(options = {}) {
|
|
25
|
+
return createLintStagedConfig(options);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// src/cli/init.ts
|
|
29
|
+
import { resolve as resolve4 } from "path";
|
|
30
|
+
import { unlinkSync, existsSync as existsSync4, rmSync } from "fs";
|
|
31
|
+
import chalk from "chalk";
|
|
32
|
+
import ora from "ora";
|
|
33
|
+
import { execa as execa2 } from "execa";
|
|
34
|
+
|
|
35
|
+
// src/utils/package-manager.ts
|
|
36
|
+
import { existsSync } from "fs";
|
|
37
|
+
import { resolve } from "path";
|
|
38
|
+
async function detectPackageManager(cwd = process.cwd()) {
|
|
39
|
+
if (existsSync(resolve(cwd, "bun.lockb")) || existsSync(resolve(cwd, "bun.lock"))) {
|
|
40
|
+
return "bun";
|
|
41
|
+
}
|
|
42
|
+
if (existsSync(resolve(cwd, "pnpm-lock.yaml"))) {
|
|
43
|
+
return "pnpm";
|
|
44
|
+
}
|
|
45
|
+
if (existsSync(resolve(cwd, "yarn.lock"))) {
|
|
46
|
+
return "yarn";
|
|
47
|
+
}
|
|
48
|
+
if (existsSync(resolve(cwd, "package-lock.json"))) {
|
|
49
|
+
return "npm";
|
|
50
|
+
}
|
|
51
|
+
return "npm";
|
|
52
|
+
}
|
|
53
|
+
function getInstallCommand(pm) {
|
|
54
|
+
const commands = {
|
|
55
|
+
npm: "npm install --save-dev",
|
|
56
|
+
yarn: "yarn add --dev",
|
|
57
|
+
pnpm: "pnpm add -D",
|
|
58
|
+
bun: "bun add --dev"
|
|
59
|
+
};
|
|
60
|
+
return commands[pm];
|
|
61
|
+
}
|
|
62
|
+
function getExecCommand(pm) {
|
|
63
|
+
const commands = {
|
|
64
|
+
npm: "npx --no",
|
|
65
|
+
yarn: "yarn",
|
|
66
|
+
pnpm: "pnpm dlx",
|
|
67
|
+
bun: "bunx"
|
|
68
|
+
};
|
|
69
|
+
return commands[pm];
|
|
70
|
+
}
|
|
71
|
+
function getPackageManagerName(pm) {
|
|
72
|
+
const names = {
|
|
73
|
+
npm: "npm",
|
|
74
|
+
yarn: "Yarn",
|
|
75
|
+
pnpm: "pnpm",
|
|
76
|
+
bun: "Bun"
|
|
77
|
+
};
|
|
78
|
+
return names[pm];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/utils/git.ts
|
|
82
|
+
import { existsSync as existsSync2 } from "fs";
|
|
83
|
+
import { resolve as resolve2 } from "path";
|
|
84
|
+
import { execa } from "execa";
|
|
85
|
+
function isGitRepository(cwd = process.cwd()) {
|
|
86
|
+
return existsSync2(resolve2(cwd, ".git"));
|
|
87
|
+
}
|
|
88
|
+
async function initGitRepository(cwd = process.cwd()) {
|
|
89
|
+
if (!isGitRepository(cwd)) {
|
|
90
|
+
await execa("git", ["init"], { cwd });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/utils/file.ts
|
|
95
|
+
import { existsSync as existsSync3 } from "fs";
|
|
96
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
97
|
+
import { resolve as resolve3, dirname } from "path";
|
|
98
|
+
function fileExists(filePath) {
|
|
99
|
+
return existsSync3(filePath);
|
|
100
|
+
}
|
|
101
|
+
async function readFileContent(filePath) {
|
|
102
|
+
return await readFile(filePath, "utf-8");
|
|
103
|
+
}
|
|
104
|
+
async function writeFileContent(filePath, content) {
|
|
105
|
+
const dir = dirname(filePath);
|
|
106
|
+
if (!existsSync3(dir)) {
|
|
107
|
+
await mkdir(dir, { recursive: true });
|
|
108
|
+
}
|
|
109
|
+
await writeFile(filePath, content, "utf-8");
|
|
110
|
+
}
|
|
111
|
+
async function readJsonFile(filePath) {
|
|
112
|
+
const content = await readFileContent(filePath);
|
|
113
|
+
return JSON.parse(content);
|
|
114
|
+
}
|
|
115
|
+
async function writeJsonFile(filePath, data, pretty = true) {
|
|
116
|
+
const content = pretty ? JSON.stringify(data, null, 2) + "\n" : JSON.stringify(data);
|
|
117
|
+
await writeFileContent(filePath, content);
|
|
118
|
+
}
|
|
119
|
+
async function updatePackageJson(updates, cwd = process.cwd()) {
|
|
120
|
+
const packageJsonPath = resolve3(cwd, "package.json");
|
|
121
|
+
const packageJson = await readJsonFile(packageJsonPath);
|
|
122
|
+
const updated = { ...packageJson, ...updates };
|
|
123
|
+
await writeJsonFile(packageJsonPath, updated);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/cli/init.ts
|
|
127
|
+
var BRAND = "#7C3AED";
|
|
128
|
+
var S = {
|
|
129
|
+
LOGO: chalk.hex(BRAND).bold("[RS]"),
|
|
130
|
+
OK: chalk.green("\u2714"),
|
|
131
|
+
FAIL: chalk.red("\u2716"),
|
|
132
|
+
WARN: chalk.yellow("\u25B2"),
|
|
133
|
+
STEP: chalk.hex(BRAND)("\u25C6"),
|
|
134
|
+
ARROW: chalk.cyan("\u25B8"),
|
|
135
|
+
DOT: chalk.gray("\u25CF"),
|
|
136
|
+
INFO: chalk.blue("\u2139"),
|
|
137
|
+
LINE: chalk.gray("\u2500".repeat(48))
|
|
138
|
+
};
|
|
139
|
+
var PRESETS = {
|
|
140
|
+
minimal: {
|
|
141
|
+
name: "\u6781\u7B80\u6A21\u5F0F",
|
|
142
|
+
desc: "\u4EC5 Git \u63D0\u4EA4\u89C4\u8303 (Commitizen + Commitlint)",
|
|
143
|
+
features: {
|
|
144
|
+
eslint: false,
|
|
145
|
+
lintStaged: false,
|
|
146
|
+
prettier: false,
|
|
147
|
+
oxlint: false,
|
|
148
|
+
editorconfig: false
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
standard: {
|
|
152
|
+
name: "\u6807\u51C6\u6A21\u5F0F",
|
|
153
|
+
desc: "\u63D0\u4EA4\u89C4\u8303 + \u4EE3\u7801\u8D28\u91CF\u68C0\u67E5 (+ ESLint + lint-staged)",
|
|
154
|
+
features: {
|
|
155
|
+
eslint: true,
|
|
156
|
+
lintStaged: true,
|
|
157
|
+
prettier: false,
|
|
158
|
+
oxlint: false,
|
|
159
|
+
editorconfig: true
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
full: {
|
|
163
|
+
name: "\u5B8C\u6574\u6A21\u5F0F",
|
|
164
|
+
desc: "\u5168\u90E8\u5DE5\u5177\u94FE (+ Prettier + Oxlint + EditorConfig)",
|
|
165
|
+
features: {
|
|
166
|
+
eslint: true,
|
|
167
|
+
lintStaged: true,
|
|
168
|
+
prettier: true,
|
|
169
|
+
oxlint: true,
|
|
170
|
+
editorconfig: true
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
async function init(options = {}) {
|
|
175
|
+
const cwd = options.cwd || process.cwd();
|
|
176
|
+
printBanner();
|
|
177
|
+
console.log(` ${S.STEP} ${chalk.bold("\u73AF\u5883\u68C0\u6D4B")}`);
|
|
178
|
+
console.log();
|
|
179
|
+
if (!isGitRepository(cwd)) {
|
|
180
|
+
const spinner = ora({
|
|
181
|
+
text: chalk.gray("\u521D\u59CB\u5316 Git \u4ED3\u5E93..."),
|
|
182
|
+
prefixText: " ",
|
|
183
|
+
spinner: "dots"
|
|
184
|
+
}).start();
|
|
185
|
+
await initGitRepository(cwd);
|
|
186
|
+
spinner.succeed(chalk.white("Git \u4ED3\u5E93\u521D\u59CB\u5316\u5B8C\u6210"));
|
|
187
|
+
} else {
|
|
188
|
+
console.log(` ${S.OK} Git \u4ED3\u5E93\u5DF2\u5C31\u7EEA`);
|
|
189
|
+
}
|
|
190
|
+
const pm = await detectPackageManager(cwd);
|
|
191
|
+
const pmName = getPackageManagerName(pm);
|
|
192
|
+
console.log(` ${S.OK} \u5305\u7BA1\u7406\u5668: ${chalk.cyan.bold(pmName)}`);
|
|
193
|
+
console.log();
|
|
194
|
+
let features;
|
|
195
|
+
let eslintOpts = {
|
|
196
|
+
framework: "vue",
|
|
197
|
+
typescript: true,
|
|
198
|
+
jsdoc: false
|
|
199
|
+
};
|
|
200
|
+
if (options.ci) {
|
|
201
|
+
const presetId = options.preset || "standard";
|
|
202
|
+
if (presetId === "custom") {
|
|
203
|
+
features = {
|
|
204
|
+
eslint: true,
|
|
205
|
+
lintStaged: true,
|
|
206
|
+
prettier: options.prettier ?? true,
|
|
207
|
+
oxlint: options.oxlint ?? true,
|
|
208
|
+
editorconfig: true
|
|
209
|
+
};
|
|
210
|
+
} else {
|
|
211
|
+
features = { ...PRESETS[presetId].features };
|
|
212
|
+
}
|
|
213
|
+
if (options.prettier !== void 0) features.prettier = options.prettier;
|
|
214
|
+
if (options.oxlint !== void 0) features.oxlint = options.oxlint;
|
|
215
|
+
const jsdocDefault = presetId === "full" ? true : false;
|
|
216
|
+
eslintOpts = {
|
|
217
|
+
framework: options.framework || "vue",
|
|
218
|
+
typescript: options.typescript ?? true,
|
|
219
|
+
jsdoc: options.jsdoc ?? jsdocDefault
|
|
220
|
+
};
|
|
221
|
+
console.log(
|
|
222
|
+
` ${S.INFO} ${chalk.gray("CI \u6A21\u5F0F")} ${chalk.white(
|
|
223
|
+
"\u9884\u8BBE:"
|
|
224
|
+
)} ${chalk.cyan(presetId)}`
|
|
225
|
+
);
|
|
226
|
+
console.log();
|
|
227
|
+
} else {
|
|
228
|
+
const result = await interactiveSetup(options);
|
|
229
|
+
features = result.features;
|
|
230
|
+
eslintOpts = result.eslintOpts;
|
|
231
|
+
}
|
|
232
|
+
printSummary(features, eslintOpts, pmName);
|
|
233
|
+
if (!options.ci) {
|
|
234
|
+
const { confirm } = await import("@inquirer/prompts");
|
|
235
|
+
const proceed = await confirm({
|
|
236
|
+
message: chalk.white("\u786E\u8BA4\u4EE5\u4E0A\u914D\u7F6E\u5E76\u5F00\u59CB\u5B89\u88C5?"),
|
|
237
|
+
default: true,
|
|
238
|
+
theme: { prefix: ` ${S.ARROW}` }
|
|
239
|
+
});
|
|
240
|
+
if (!proceed) {
|
|
241
|
+
console.log();
|
|
242
|
+
console.log(` ${S.INFO} ${chalk.gray("\u91CD\u65B0\u9009\u62E9\u914D\u7F6E...")}`);
|
|
243
|
+
console.log();
|
|
244
|
+
const result = await interactiveSetup(options);
|
|
245
|
+
features = result.features;
|
|
246
|
+
eslintOpts = result.eslintOpts;
|
|
247
|
+
printSummary(features, eslintOpts, pmName);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
console.log();
|
|
251
|
+
await installDependencies(cwd, pm, features, eslintOpts);
|
|
252
|
+
await generateConfigFiles(cwd, features, eslintOpts);
|
|
253
|
+
await setupHusky(cwd, pm, features);
|
|
254
|
+
await addPackageScripts(cwd, pm, features);
|
|
255
|
+
printCompletion(pm, features);
|
|
256
|
+
}
|
|
257
|
+
function printBanner() {
|
|
258
|
+
console.log();
|
|
259
|
+
console.log(S.LINE);
|
|
260
|
+
console.log(
|
|
261
|
+
` ${S.LOGO} ${chalk.bold("Robot Standards")} ${chalk.gray("v1.0.0")}`
|
|
262
|
+
);
|
|
263
|
+
console.log(` ${chalk.gray("\u96F6\u914D\u7F6E \xB7 \u6A21\u5757\u5316 \xB7 Git \u5DE5\u7A0B\u5316\u6807\u51C6\u5DE5\u5177\u5305")}`);
|
|
264
|
+
console.log(S.LINE);
|
|
265
|
+
console.log();
|
|
266
|
+
}
|
|
267
|
+
async function interactiveSetup(options) {
|
|
268
|
+
const { select, checkbox, confirm } = await import("@inquirer/prompts");
|
|
269
|
+
while (true) {
|
|
270
|
+
console.log(` ${S.STEP} ${chalk.bold("\u9009\u62E9\u6A21\u5F0F")}`);
|
|
271
|
+
console.log();
|
|
272
|
+
const presetId = await select({
|
|
273
|
+
message: chalk.white("\u9009\u62E9\u9884\u8BBE\u65B9\u6848"),
|
|
274
|
+
choices: [
|
|
275
|
+
{
|
|
276
|
+
name: `\u6781\u7B80\u6A21\u5F0F ${chalk.gray(
|
|
277
|
+
"\u2500\u2500 \u4EC5\u63D0\u4EA4\u89C4\u8303 (Commitizen + Commitlint)"
|
|
278
|
+
)}`,
|
|
279
|
+
value: "minimal",
|
|
280
|
+
description: chalk.gray("\u9002\u5408\u53EA\u9700\u89C4\u8303\u63D0\u4EA4\u4FE1\u606F\u7684\u9879\u76EE")
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
name: `\u6807\u51C6\u6A21\u5F0F ${chalk.gray("\u2500\u2500 \u63D0\u4EA4\u89C4\u8303 + \u4EE3\u7801\u68C0\u67E5 (+ ESLint)")}`,
|
|
284
|
+
value: "standard",
|
|
285
|
+
description: chalk.gray("\u9002\u5408\u5927\u591A\u6570\u9879\u76EE")
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
name: `\u5B8C\u6574\u6A21\u5F0F ${chalk.gray(
|
|
289
|
+
"\u2500\u2500 \u5168\u90E8\u5DE5\u5177\u94FE (+ Prettier + Oxlint)"
|
|
290
|
+
)} ${chalk.hex(BRAND)("\u4E3B\u9879\u76EE(Robot_Admin)")}`,
|
|
291
|
+
value: "full",
|
|
292
|
+
description: chalk.gray("\u5168\u9762\u4EE3\u7801\u8D28\u91CF\u7BA1\u63A7")
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: `\u81EA\u5B9A\u4E49 ${chalk.gray("\u2500\u2500 \u81EA\u7531\u7EC4\u5408\u9700\u8981\u7684\u5DE5\u5177\u94FE")}`,
|
|
296
|
+
value: "custom",
|
|
297
|
+
description: chalk.gray("\u7CBE\u786E\u63A7\u5236\u6BCF\u4E2A\u529F\u80FD\u6A21\u5757")
|
|
298
|
+
}
|
|
299
|
+
],
|
|
300
|
+
default: "standard",
|
|
301
|
+
theme: { prefix: ` ${S.ARROW}` }
|
|
302
|
+
});
|
|
303
|
+
let features;
|
|
304
|
+
if (presetId === "custom") {
|
|
305
|
+
console.log();
|
|
306
|
+
console.log(
|
|
307
|
+
` ${S.STEP} ${chalk.bold("\u9009\u62E9\u529F\u80FD")} ${chalk.gray(
|
|
308
|
+
"(Git \u63D0\u4EA4\u89C4\u8303\u9ED8\u8BA4\u5305\u542B)"
|
|
309
|
+
)}`
|
|
310
|
+
);
|
|
311
|
+
console.log();
|
|
312
|
+
const selected = await checkbox({
|
|
313
|
+
message: chalk.white("\u9009\u62E9\u9644\u52A0\u529F\u80FD (\u7A7A\u683C\u5207\u6362, \u56DE\u8F66\u786E\u8BA4)"),
|
|
314
|
+
choices: [
|
|
315
|
+
{
|
|
316
|
+
name: `ESLint ${chalk.gray("\u4EE3\u7801\u8D28\u91CF\u68C0\u67E5")}`,
|
|
317
|
+
value: "eslint"
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
name: `lint-staged ${chalk.gray("\u6682\u5B58\u533A\u589E\u91CF\u68C0\u67E5")}`,
|
|
321
|
+
value: "lintStaged"
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
name: `Prettier ${chalk.gray("\u4EE3\u7801\u81EA\u52A8\u683C\u5F0F\u5316")}`,
|
|
325
|
+
value: "prettier"
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
name: `Oxlint ${chalk.gray(
|
|
329
|
+
"\u9AD8\u6027\u80FD Lint \u5F15\u64CE (50x faster)"
|
|
330
|
+
)}`,
|
|
331
|
+
value: "oxlint"
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
name: `EditorConfig ${chalk.gray("\u7F16\u8F91\u5668\u7EDF\u4E00\u914D\u7F6E")}`,
|
|
335
|
+
value: "editorconfig"
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
name: chalk.yellow("\u21A9 \u8FD4\u56DE\u4E0A\u4E00\u6B65"),
|
|
339
|
+
value: "__back__"
|
|
340
|
+
}
|
|
341
|
+
],
|
|
342
|
+
theme: { prefix: ` ${S.ARROW}` }
|
|
343
|
+
});
|
|
344
|
+
if (selected.includes("__back__")) continue;
|
|
345
|
+
features = {
|
|
346
|
+
eslint: selected.includes("eslint"),
|
|
347
|
+
lintStaged: selected.includes("lintStaged"),
|
|
348
|
+
prettier: selected.includes("prettier"),
|
|
349
|
+
oxlint: selected.includes("oxlint"),
|
|
350
|
+
editorconfig: selected.includes("editorconfig")
|
|
351
|
+
};
|
|
352
|
+
if (features.oxlint && !features.eslint) {
|
|
353
|
+
console.log(
|
|
354
|
+
`
|
|
355
|
+
${S.INFO} ${chalk.gray(
|
|
356
|
+
"Oxlint \u9700\u8981 ESLint \u914D\u5408\uFF0C\u5DF2\u81EA\u52A8\u542F\u7528 ESLint"
|
|
357
|
+
)}`
|
|
358
|
+
);
|
|
359
|
+
features.eslint = true;
|
|
360
|
+
}
|
|
361
|
+
if (features.lintStaged && !features.eslint && !features.prettier) {
|
|
362
|
+
console.log(
|
|
363
|
+
`
|
|
364
|
+
${S.INFO} ${chalk.gray(
|
|
365
|
+
"lint-staged \u9700\u8981 ESLint \u6216 Prettier\uFF0C\u5DF2\u81EA\u52A8\u542F\u7528 ESLint"
|
|
366
|
+
)}`
|
|
367
|
+
);
|
|
368
|
+
features.eslint = true;
|
|
369
|
+
}
|
|
370
|
+
} else {
|
|
371
|
+
features = { ...PRESETS[presetId].features };
|
|
372
|
+
}
|
|
373
|
+
let eslintOpts = {
|
|
374
|
+
framework: "vue",
|
|
375
|
+
typescript: true,
|
|
376
|
+
jsdoc: false
|
|
377
|
+
};
|
|
378
|
+
if (features.eslint) {
|
|
379
|
+
console.log();
|
|
380
|
+
console.log(` ${S.STEP} ${chalk.bold("ESLint \u914D\u7F6E")}`);
|
|
381
|
+
console.log();
|
|
382
|
+
const framework = await select({
|
|
383
|
+
message: chalk.white("\u9879\u76EE\u6846\u67B6"),
|
|
384
|
+
choices: [
|
|
385
|
+
{
|
|
386
|
+
name: "Vue 3",
|
|
387
|
+
value: "vue"
|
|
388
|
+
},
|
|
389
|
+
{ name: "React", value: "react" },
|
|
390
|
+
{ name: "Vanilla JS / TS", value: "vanilla" },
|
|
391
|
+
{
|
|
392
|
+
name: chalk.yellow("\u21A9 \u8FD4\u56DE\u4E0A\u4E00\u6B65"),
|
|
393
|
+
value: "__back__"
|
|
394
|
+
}
|
|
395
|
+
],
|
|
396
|
+
default: options.framework || "vue",
|
|
397
|
+
theme: { prefix: ` ${S.ARROW}` }
|
|
398
|
+
});
|
|
399
|
+
if (framework === "__back__") continue;
|
|
400
|
+
const typescript = await confirm({
|
|
401
|
+
message: chalk.white("\u4F7F\u7528 TypeScript"),
|
|
402
|
+
default: options.typescript ?? true,
|
|
403
|
+
theme: { prefix: ` ${S.ARROW}` }
|
|
404
|
+
});
|
|
405
|
+
const jsdoc = await confirm({
|
|
406
|
+
message: chalk.white("\u5F3A\u5236 JSDoc \u6CE8\u91CA"),
|
|
407
|
+
default: options.jsdoc ?? true,
|
|
408
|
+
theme: { prefix: ` ${S.ARROW}` }
|
|
409
|
+
});
|
|
410
|
+
eslintOpts = { framework, typescript, jsdoc };
|
|
411
|
+
}
|
|
412
|
+
return { features, eslintOpts };
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function printSummary(features, eslintOpts, pmName) {
|
|
416
|
+
console.log();
|
|
417
|
+
console.log(` ${S.STEP} ${chalk.bold("\u914D\u7F6E\u6458\u8981")}`);
|
|
418
|
+
console.log();
|
|
419
|
+
console.log(
|
|
420
|
+
` ${S.OK} ${chalk.white("\u6838\u5FC3")} Commitizen + Commitlint + Husky`
|
|
421
|
+
);
|
|
422
|
+
if (features.eslint) {
|
|
423
|
+
const fw = eslintOpts.framework === "vue" ? "Vue 3" : eslintOpts.framework === "react" ? "React" : "Vanilla";
|
|
424
|
+
const ts = eslintOpts.typescript ? " + TS" : "";
|
|
425
|
+
const jsdoc = eslintOpts.jsdoc ? " + JSDoc" : "";
|
|
426
|
+
console.log(
|
|
427
|
+
` ${S.OK} ${chalk.white("\u68C0\u67E5")} ESLint (${fw}${ts}${jsdoc})`
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
if (features.lintStaged) {
|
|
431
|
+
console.log(` ${S.OK} ${chalk.white("\u6682\u5B58")} lint-staged`);
|
|
432
|
+
}
|
|
433
|
+
if (features.oxlint) {
|
|
434
|
+
console.log(
|
|
435
|
+
` ${S.OK} ${chalk.white("\u52A0\u901F")} Oxlint ${chalk.gray("(50x faster)")}`
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
if (features.prettier) {
|
|
439
|
+
console.log(` ${S.OK} ${chalk.white("\u683C\u5F0F")} Prettier`);
|
|
440
|
+
}
|
|
441
|
+
if (features.editorconfig) {
|
|
442
|
+
console.log(` ${S.OK} ${chalk.white("\u7F16\u8F91")} EditorConfig`);
|
|
443
|
+
}
|
|
444
|
+
console.log(` ${S.DOT} ${chalk.gray("\u7BA1\u7406")} ${pmName}`);
|
|
445
|
+
console.log();
|
|
446
|
+
}
|
|
447
|
+
async function installDependencies(cwd, pm, features, eslintOpts) {
|
|
448
|
+
const spinner = ora({
|
|
449
|
+
text: chalk.gray("\u5206\u6790\u4F9D\u8D56..."),
|
|
450
|
+
prefixText: " ",
|
|
451
|
+
spinner: "dots"
|
|
452
|
+
}).start();
|
|
453
|
+
const deps = [
|
|
454
|
+
"@commitlint/cli",
|
|
455
|
+
"@commitlint/config-conventional",
|
|
456
|
+
"commitizen",
|
|
457
|
+
"cz-customizable",
|
|
458
|
+
"husky"
|
|
459
|
+
];
|
|
460
|
+
if (features.eslint) {
|
|
461
|
+
deps.push("eslint");
|
|
462
|
+
if (eslintOpts.framework === "vue") {
|
|
463
|
+
deps.push("eslint-plugin-vue", "@vue/eslint-config-typescript");
|
|
464
|
+
}
|
|
465
|
+
if (eslintOpts.typescript) {
|
|
466
|
+
deps.push(
|
|
467
|
+
"@typescript-eslint/eslint-plugin",
|
|
468
|
+
"@typescript-eslint/parser"
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
if (eslintOpts.jsdoc) {
|
|
472
|
+
deps.push("eslint-plugin-jsdoc");
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
if (features.lintStaged) {
|
|
476
|
+
deps.push("lint-staged");
|
|
477
|
+
}
|
|
478
|
+
if (features.oxlint) {
|
|
479
|
+
deps.push("oxlint", "eslint-plugin-oxlint");
|
|
480
|
+
}
|
|
481
|
+
if (features.prettier) {
|
|
482
|
+
deps.push("prettier");
|
|
483
|
+
if (features.eslint && eslintOpts.framework === "vue") {
|
|
484
|
+
deps.push("@vue/eslint-config-prettier");
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
spinner.text = chalk.gray(`\u5B89\u88C5 ${deps.length} \u4E2A\u4F9D\u8D56...`);
|
|
488
|
+
try {
|
|
489
|
+
const installCmd = getInstallCommand(pm);
|
|
490
|
+
await execa2(
|
|
491
|
+
installCmd.split(" ")[0],
|
|
492
|
+
[...installCmd.split(" ").slice(1), ...deps],
|
|
493
|
+
{ cwd, stdio: "pipe" }
|
|
494
|
+
);
|
|
495
|
+
spinner.succeed(
|
|
496
|
+
chalk.white("\u4F9D\u8D56\u5B89\u88C5\u5B8C\u6210 ") + chalk.gray(`(${deps.length} packages)`)
|
|
497
|
+
);
|
|
498
|
+
} catch (error) {
|
|
499
|
+
spinner.fail(chalk.red("\u4F9D\u8D56\u5B89\u88C5\u5931\u8D25"));
|
|
500
|
+
throw error;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
async function generateConfigFiles(cwd, features, eslintOpts) {
|
|
504
|
+
const spinner = ora({
|
|
505
|
+
text: chalk.gray("\u751F\u6210\u914D\u7F6E\u6587\u4EF6..."),
|
|
506
|
+
prefixText: " ",
|
|
507
|
+
spinner: "dots"
|
|
508
|
+
}).start();
|
|
509
|
+
const generated = [];
|
|
510
|
+
try {
|
|
511
|
+
const czConfig = `/*
|
|
512
|
+
* Commitizen \u81EA\u5B9A\u4E49\u914D\u7F6E (cz-customizable)
|
|
513
|
+
* @generated by @robot-admin/git-standards
|
|
514
|
+
*
|
|
515
|
+
* \u76F4\u63A5\u4FEE\u6539\u6B64\u6587\u4EF6\u5373\u53EF\u81EA\u5B9A\u4E49\u63D0\u4EA4\u89C4\u8303
|
|
516
|
+
*/
|
|
517
|
+
module.exports = {
|
|
518
|
+
scopes: [],
|
|
519
|
+
allowEmptyScopes: false,
|
|
520
|
+
allowCustomScopes: true,
|
|
521
|
+
|
|
522
|
+
types: [
|
|
523
|
+
{ value: 'wip', name: 'wip: \u{1F6A7} \u5F00\u53D1\u4E2D' },
|
|
524
|
+
{ value: 'feat', name: 'feat: \u{1F3AF} \u65B0\u529F\u80FD' },
|
|
525
|
+
{ value: 'fix', name: 'fix: \u{1F41B} Bug \u4FEE\u590D' },
|
|
526
|
+
{ value: 'perf', name: 'perf: \u26A1\uFE0F \u6027\u80FD\u4F18\u5316' },
|
|
527
|
+
{ value: 'deps', name: 'deps: \u{1F4E6} \u4F9D\u8D56\u66F4\u65B0' },
|
|
528
|
+
{ value: 'refactor', name: 'refactor: \u267B\uFE0F \u91CD\u6784' },
|
|
529
|
+
{ value: 'docs', name: 'docs: \u{1F4DA} \u6587\u6863\u53D8\u66F4' },
|
|
530
|
+
{ value: 'test', name: 'test: \u{1F50E} \u6D4B\u8BD5\u76F8\u5173' },
|
|
531
|
+
{ value: 'style', name: 'style: \u{1F484} \u4EE3\u7801\u6837\u5F0F' },
|
|
532
|
+
{ value: 'build', name: 'build: \u{1F9F3} \u6784\u5EFA/\u6253\u5305' },
|
|
533
|
+
{ value: 'chore', name: 'chore: \u{1F527} \u5176\u4ED6\u6742\u9879' },
|
|
534
|
+
{ value: 'revert', name: 'revert: \u{1F519} \u56DE\u9000' },
|
|
535
|
+
],
|
|
536
|
+
|
|
537
|
+
messages: {
|
|
538
|
+
type: '\u8BF7\u9009\u62E9\u63D0\u4EA4\u7C7B\u578B:',
|
|
539
|
+
customScope: '\u8BF7\u8F93\u5165\u4FEE\u6539\u8303\u56F4(\u5FC5\u586B\uFF0C\u683C\u5F0F\u5982\uFF1A\u6A21\u5757/\u5B50\u6A21\u5757):',
|
|
540
|
+
subject: '\u8BF7\u7B80\u8981\u63CF\u8FF0\u63D0\u4EA4(\u5FC5\u586B\uFF0C\u4E0D\u52A0\u53E5\u53F7):',
|
|
541
|
+
body: '\u8BF7\u8F93\u5165\u66F4\u8BE6\u7EC6\u7684\u8BF4\u660E(\u53EF\u9009):\\n',
|
|
542
|
+
footer: 'Footer(\u53EF\u9009): \u4F8B\u5982 "Closes #123" \u6216 "Release-As: 1.3.1"\\n',
|
|
543
|
+
confirmCommit: '\u786E\u8BA4\u63D0\u4EA4\u4EE5\u4E0A\u5185\u5BB9\uFF1F(y/n/e/h)',
|
|
544
|
+
},
|
|
545
|
+
|
|
546
|
+
skipQuestions: ['body'],
|
|
547
|
+
|
|
548
|
+
allowBreakingChanges: ['feat', 'fix', 'refactor'],
|
|
549
|
+
breakingPrefix: 'BREAKING CHANGE:',
|
|
550
|
+
|
|
551
|
+
subjectLimit: 88,
|
|
552
|
+
}
|
|
553
|
+
`;
|
|
554
|
+
await writeFileContent(resolve4(cwd, ".cz-config.js"), czConfig);
|
|
555
|
+
generated.push(".cz-config.js");
|
|
556
|
+
const commitlintConfig = `/*
|
|
557
|
+
* Commitlint \u914D\u7F6E
|
|
558
|
+
* @generated by @robot-admin/git-standards
|
|
559
|
+
*
|
|
560
|
+
* \u76F4\u63A5\u4FEE\u6539\u6B64\u6587\u4EF6\u5373\u53EF\u81EA\u5B9A\u4E49\u63D0\u4EA4\u6821\u9A8C\u89C4\u5219
|
|
561
|
+
*/
|
|
562
|
+
module.exports = {
|
|
563
|
+
extends: ['@commitlint/config-conventional'],
|
|
564
|
+
rules: {
|
|
565
|
+
'type-enum': [
|
|
566
|
+
2,
|
|
567
|
+
'always',
|
|
568
|
+
[
|
|
569
|
+
'wip', 'feat', 'fix', 'docs', 'style', 'refactor',
|
|
570
|
+
'perf', 'test', 'chore', 'revert', 'build', 'deps',
|
|
571
|
+
],
|
|
572
|
+
],
|
|
573
|
+
'subject-case': [0],
|
|
574
|
+
},
|
|
575
|
+
}
|
|
576
|
+
`;
|
|
577
|
+
await writeFileContent(
|
|
578
|
+
resolve4(cwd, "commitlint.config.js"),
|
|
579
|
+
commitlintConfig
|
|
580
|
+
);
|
|
581
|
+
generated.push("commitlint.config.js");
|
|
582
|
+
if (features.prettier) {
|
|
583
|
+
const prettierConfig = `/*
|
|
584
|
+
* Prettier \u914D\u7F6E
|
|
585
|
+
* @generated by @robot-admin/git-standards
|
|
586
|
+
*
|
|
587
|
+
* \u76F4\u63A5\u4FEE\u6539\u6B64\u6587\u4EF6\u5373\u53EF\u81EA\u5B9A\u4E49\u683C\u5F0F\u5316\u89C4\u5219
|
|
588
|
+
*/
|
|
589
|
+
module.exports = {
|
|
590
|
+
$schema: 'https://json.schemastore.org/prettierrc',
|
|
591
|
+
semi: false,
|
|
592
|
+
singleQuote: true,
|
|
593
|
+
printWidth: 80,
|
|
594
|
+
tabWidth: 2,
|
|
595
|
+
quoteProps: 'as-needed',
|
|
596
|
+
trailingComma: 'es5',
|
|
597
|
+
bracketSpacing: true,
|
|
598
|
+
jsxSingleQuote: true,
|
|
599
|
+
arrowParens: 'avoid',
|
|
600
|
+
endOfLine: 'auto',
|
|
601
|
+
htmlWhitespaceSensitivity: 'strict',
|
|
602
|
+
vueIndentScriptAndStyle: true,
|
|
603
|
+
singleAttributePerLine: true,
|
|
604
|
+
}
|
|
605
|
+
`;
|
|
606
|
+
await writeFileContent(resolve4(cwd, ".prettierrc.js"), prettierConfig);
|
|
607
|
+
generated.push(".prettierrc.js");
|
|
608
|
+
}
|
|
609
|
+
if (features.eslint) {
|
|
610
|
+
const hasOxlint = features.oxlint;
|
|
611
|
+
const hasPrettier = features.prettier;
|
|
612
|
+
const hasJsdoc = eslintOpts.jsdoc;
|
|
613
|
+
const isVue = eslintOpts.framework === "vue";
|
|
614
|
+
const isTs = eslintOpts.typescript;
|
|
615
|
+
const importLines = [];
|
|
616
|
+
if (isVue) importLines.push("import pluginVue from 'eslint-plugin-vue'");
|
|
617
|
+
if (isVue && isTs) {
|
|
618
|
+
importLines.push(
|
|
619
|
+
"import {\n defineConfigWithVueTs,\n vueTsConfigs,\n} from '@vue/eslint-config-typescript'"
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
if (hasOxlint)
|
|
623
|
+
importLines.push("import oxlint from 'eslint-plugin-oxlint'");
|
|
624
|
+
if (hasPrettier && isVue) {
|
|
625
|
+
importLines.push(
|
|
626
|
+
"import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'"
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
if (hasJsdoc)
|
|
630
|
+
importLines.push("import jsdocPlugin from 'eslint-plugin-jsdoc'");
|
|
631
|
+
const fileExts = isTs ? "js,ts,mts,tsx,vue" : "js,jsx,vue";
|
|
632
|
+
const vue2DeprecationRules = isVue ? `
|
|
633
|
+
//! \u4E3B\u52A8\u7981\u6B62 Vue 2 \u5199\u6CD5
|
|
634
|
+
'vue/no-deprecated-props-default-this': 'error',
|
|
635
|
+
'vue/no-deprecated-events-api': 'error',
|
|
636
|
+
'vue/no-deprecated-filter': 'error',
|
|
637
|
+
'vue/no-deprecated-functional-template': 'error',
|
|
638
|
+
` : "";
|
|
639
|
+
const vueComponentRules = isVue ? `
|
|
640
|
+
// Vue \u89C4\u8303
|
|
641
|
+
//! PascalCase \u547D\u540D\u89C4\u8303
|
|
642
|
+
'vue/component-name-in-template-casing': [
|
|
643
|
+
'error',
|
|
644
|
+
'PascalCase',
|
|
645
|
+
{
|
|
646
|
+
registeredComponentsOnly: false,
|
|
647
|
+
ignores: [
|
|
648
|
+
'router-view',
|
|
649
|
+
'router-link',
|
|
650
|
+
'transition',
|
|
651
|
+
'draggable',
|
|
652
|
+
'/^icon-/i',
|
|
653
|
+
'/^C_/',
|
|
654
|
+
'/^c_/',
|
|
655
|
+
'v-md-editor',
|
|
656
|
+
],
|
|
657
|
+
},
|
|
658
|
+
],
|
|
659
|
+
'vue/multi-word-component-names': [
|
|
660
|
+
'error',
|
|
661
|
+
{
|
|
662
|
+
ignores: ['index'],
|
|
663
|
+
},
|
|
664
|
+
],
|
|
665
|
+
//! \u7981\u6B62\u5728\u6A21\u677F\u4E2D\u6CE8\u518C\u4F46\u672A\u4F7F\u7528\u7684\u7EC4\u4EF6
|
|
666
|
+
'vue/no-unused-components': 'error',
|
|
667
|
+
${vue2DeprecationRules}` : "";
|
|
668
|
+
const jsdocBlock = hasJsdoc ? `
|
|
669
|
+
//MARK: \u81EA\u5B9A\u4E49\u89C4\u5219\u7EC4\uFF08\u4F18\u5148\u7EA7\u6700\u9AD8\uFF09
|
|
670
|
+
{
|
|
671
|
+
plugins: {
|
|
672
|
+
jsdoc: jsdocPlugin,
|
|
673
|
+
},
|
|
674
|
+
rules: {
|
|
675
|
+
//! JSDoc \u6CE8\u91CA\u89C4\u5219
|
|
676
|
+
'jsdoc/require-jsdoc': [
|
|
677
|
+
'error',
|
|
678
|
+
{
|
|
679
|
+
require: {
|
|
680
|
+
FunctionDeclaration: true,
|
|
681
|
+
MethodDefinition: true,
|
|
682
|
+
ClassDeclaration: true,
|
|
683
|
+
ArrowFunctionExpression: false,
|
|
684
|
+
FunctionExpression: true,
|
|
685
|
+
},
|
|
686
|
+
contexts: [
|
|
687
|
+
'FunctionDeclaration',
|
|
688
|
+
'ClassDeclaration',
|
|
689
|
+
'ClassProperty',
|
|
690
|
+
'MethodDefinition',
|
|
691
|
+
'FunctionExpression',
|
|
692
|
+
],
|
|
693
|
+
checkConstructors: true,
|
|
694
|
+
checkGetters: true,
|
|
695
|
+
checkSetters: true,
|
|
696
|
+
},
|
|
697
|
+
],
|
|
698
|
+
` : `
|
|
699
|
+
// \u81EA\u5B9A\u4E49\u89C4\u5219\u7EC4
|
|
700
|
+
{
|
|
701
|
+
rules: {
|
|
702
|
+
`;
|
|
703
|
+
const fileTypeOverrides = isTs ? `
|
|
704
|
+
//MARK: \u6587\u4EF6\u7C7B\u578B\u8986\u76D6\u89C4\u5219
|
|
705
|
+
|
|
706
|
+
//! \u53D8\u91CF\u4F7F\u7528\u89C4\u5219
|
|
707
|
+
{
|
|
708
|
+
files: ['**/*.js'],
|
|
709
|
+
rules: {
|
|
710
|
+
'no-unused-vars': 'error',
|
|
711
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
712
|
+
},
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
files: ['**/*.{ts,mts,tsx,vue}'],
|
|
716
|
+
rules: {
|
|
717
|
+
'no-unused-vars': 'off',
|
|
718
|
+
'@typescript-eslint/no-unused-vars': 'error',
|
|
719
|
+
},
|
|
720
|
+
},
|
|
721
|
+
` : "";
|
|
722
|
+
const jsdocWhitelist = hasJsdoc ? `
|
|
723
|
+
//MARK: JSDoc \u767D\u540D\u5355\u8986\u76D6\u89C4\u5219
|
|
724
|
+
{
|
|
725
|
+
files: [
|
|
726
|
+
'src/router/**/*.ts',
|
|
727
|
+
'src/stores/**/*.ts',
|
|
728
|
+
'src/views/**/components/*.vue',
|
|
729
|
+
],
|
|
730
|
+
rules: {
|
|
731
|
+
'jsdoc/require-jsdoc': 'off',
|
|
732
|
+
'@typescript-eslint/require-jsdoc': 'off',
|
|
733
|
+
},
|
|
734
|
+
},
|
|
735
|
+
` : "";
|
|
736
|
+
const ignoreAssets = `
|
|
737
|
+
//MARK: ESLINT \u767D\u540D\u5355\u914D\u7F6E\u7EC4
|
|
738
|
+
{
|
|
739
|
+
name: 'app/ignore-assets',
|
|
740
|
+
ignores: [
|
|
741
|
+
'src/assets/images/**/*',
|
|
742
|
+
'**/*.d.ts',
|
|
743
|
+
'**/auto-imports.d.ts',
|
|
744
|
+
'src/views/**/components/*.vue',
|
|
745
|
+
'scripts/**/*',
|
|
746
|
+
],
|
|
747
|
+
},
|
|
748
|
+
`;
|
|
749
|
+
const tsRules = isTs ? `
|
|
750
|
+
//! \u5173\u95ED\u4E0E oxlint \u91CD\u590D\u7684 ESLint \u89C4\u5219
|
|
751
|
+
'no-undef': 'off',
|
|
752
|
+
|
|
753
|
+
//! \u5F15\u53F7\u89C4\u8303
|
|
754
|
+
'@typescript-eslint/quotes': ['error', 'single'],${isVue ? "\n 'vue/html-quotes': ['error', 'double']," : ""}
|
|
755
|
+
|
|
756
|
+
//! TypeScript \u5B89\u5168
|
|
757
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
758
|
+
'@typescript-eslint/ban-ts-comment': [
|
|
759
|
+
'error',
|
|
760
|
+
{
|
|
761
|
+
'ts-ignore': 'allow-with-description',
|
|
762
|
+
},
|
|
763
|
+
],
|
|
764
|
+
|
|
765
|
+
//! \u8868\u8FBE\u5F0F\u89C4\u8303
|
|
766
|
+
'@typescript-eslint/no-unused-expressions': [
|
|
767
|
+
'error',
|
|
768
|
+
{
|
|
769
|
+
allowShortCircuit: true,
|
|
770
|
+
allowTernary: false,
|
|
771
|
+
allowTaggedTemplates: false,
|
|
772
|
+
enforceForJSX: true,
|
|
773
|
+
},
|
|
774
|
+
],
|
|
775
|
+
` : "";
|
|
776
|
+
const useWrapper = isVue && isTs;
|
|
777
|
+
const wrapperStart = useWrapper ? "export default defineConfigWithVueTs(" : "export default [";
|
|
778
|
+
const wrapperEnd = useWrapper ? ")" : "]";
|
|
779
|
+
const oxlintLine = hasOxlint ? "\n ...oxlint.configs['flat/recommended'], // \u9AD8\u6027\u80FD\u57FA\u7840\u6821\u9A8C\n" : "";
|
|
780
|
+
const vueLine = isVue ? `
|
|
781
|
+
//! \u5FFD\u7565\u8F6C\u4E49\u5B57\u7B26
|
|
782
|
+
{
|
|
783
|
+
rules: {
|
|
784
|
+
'no-useless-escape': 'off',
|
|
785
|
+
},
|
|
786
|
+
},
|
|
787
|
+
|
|
788
|
+
pluginVue.configs['flat/essential'], // Vue \u4E13\u7528\u89C4\u5219` : "";
|
|
789
|
+
const tsLine = isVue && isTs ? "\n vueTsConfigs.recommended, // TS \u4E13\u7528\u89C4\u5219" : "";
|
|
790
|
+
const skipLine = hasPrettier && isVue ? "\n skipFormatting" : "";
|
|
791
|
+
const eslintConfig = `/*
|
|
792
|
+
* ESLint Flat Config
|
|
793
|
+
* @generated by @robot-admin/git-standards
|
|
794
|
+
*
|
|
795
|
+
* \u76F4\u63A5\u4FEE\u6539\u6B64\u6587\u4EF6\u5373\u53EF\u81EA\u5B9A\u4E49 ESLint \u89C4\u5219
|
|
796
|
+
*/
|
|
797
|
+
${importLines.join("\n")}
|
|
798
|
+
|
|
799
|
+
${wrapperStart}
|
|
800
|
+
//MARK: \u57FA\u7840\u914D\u7F6E\u7EC4
|
|
801
|
+
{
|
|
802
|
+
name: 'app/files-to-lint',
|
|
803
|
+
files: ['**/*.{${fileExts}}'],
|
|
804
|
+
},
|
|
805
|
+
|
|
806
|
+
{
|
|
807
|
+
name: 'app/files-to-ignore',
|
|
808
|
+
ignores: [
|
|
809
|
+
'**/dist/**',
|
|
810
|
+
'**/dist-ssr/**',
|
|
811
|
+
'**/coverage/**',
|
|
812
|
+
],
|
|
813
|
+
},
|
|
814
|
+
|
|
815
|
+
//MARK: \u6838\u5FC3\u89C4\u5219\u7EC4\uFF08\u6309\u4F18\u5148\u7EA7\u6392\u5E8F\uFF09
|
|
816
|
+
${oxlintLine}${vueLine}${tsLine}
|
|
817
|
+
${fileTypeOverrides}
|
|
818
|
+
${jsdocBlock}${tsRules}
|
|
819
|
+
//! \u4EE3\u7801\u590D\u6742\u5EA6
|
|
820
|
+
'max-depth': ['error', 4],
|
|
821
|
+
complexity: ['warn', 10],
|
|
822
|
+
|
|
823
|
+
//! \u5F02\u6B65\u4EE3\u7801\u89C4\u8303
|
|
824
|
+
'no-await-in-loop': 'error',
|
|
825
|
+
${vueComponentRules}
|
|
826
|
+
//MARK: \u683C\u5F0F\u89C4\u8303
|
|
827
|
+
'no-irregular-whitespace': 'error',
|
|
828
|
+
'no-multi-spaces': 'error',
|
|
829
|
+
'space-infix-ops': 'error',
|
|
830
|
+
'array-bracket-spacing': ['error', 'never'],
|
|
831
|
+
'arrow-spacing': ['error', { before: true, after: true }],
|
|
832
|
+
'max-params': ['warn', 6],
|
|
833
|
+
'no-eval': 'error',
|
|
834
|
+
'prefer-const': 'warn',
|
|
835
|
+
'no-var': 'warn',
|
|
836
|
+
'prefer-destructuring': [
|
|
837
|
+
1,
|
|
838
|
+
{ object: true, array: false },
|
|
839
|
+
],
|
|
840
|
+
'no-duplicate-imports': 'error',
|
|
841
|
+
},
|
|
842
|
+
},
|
|
843
|
+
${ignoreAssets}${jsdocWhitelist}${skipLine}
|
|
844
|
+
${wrapperEnd}
|
|
845
|
+
`;
|
|
846
|
+
await writeFileContent(resolve4(cwd, "eslint.config.ts"), eslintConfig);
|
|
847
|
+
generated.push("eslint.config.ts");
|
|
848
|
+
}
|
|
849
|
+
if (features.editorconfig) {
|
|
850
|
+
const editorConfig = `# EditorConfig - \u7F16\u8F91\u5668\u7EDF\u4E00\u914D\u7F6E
|
|
851
|
+
# @generated by @robot-admin/git-standards
|
|
852
|
+
# \u53C2\u8003: https://editorconfig.org
|
|
853
|
+
|
|
854
|
+
root = true
|
|
855
|
+
|
|
856
|
+
[*]
|
|
857
|
+
charset = utf-8
|
|
858
|
+
indent_style = space
|
|
859
|
+
indent_size = 2
|
|
860
|
+
end_of_line = lf
|
|
861
|
+
insert_final_newline = true
|
|
862
|
+
trim_trailing_whitespace = true
|
|
863
|
+
|
|
864
|
+
[*.md]
|
|
865
|
+
trim_trailing_whitespace = false
|
|
866
|
+
|
|
867
|
+
[*.{yml,yaml}]
|
|
868
|
+
indent_size = 2
|
|
869
|
+
|
|
870
|
+
[Makefile]
|
|
871
|
+
indent_style = tab
|
|
872
|
+
`;
|
|
873
|
+
await writeFileContent(resolve4(cwd, ".editorconfig"), editorConfig);
|
|
874
|
+
generated.push(".editorconfig");
|
|
875
|
+
}
|
|
876
|
+
spinner.succeed(
|
|
877
|
+
chalk.white("\u914D\u7F6E\u6587\u4EF6\u751F\u6210\u5B8C\u6210 ") + chalk.gray(`(${generated.join(", ")})`)
|
|
878
|
+
);
|
|
879
|
+
} catch (error) {
|
|
880
|
+
spinner.fail(chalk.red("\u914D\u7F6E\u6587\u4EF6\u751F\u6210\u5931\u8D25"));
|
|
881
|
+
throw error;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
async function setupHusky(cwd, pm, features) {
|
|
885
|
+
const spinner = ora({
|
|
886
|
+
text: chalk.gray("\u521D\u59CB\u5316 Husky..."),
|
|
887
|
+
prefixText: " ",
|
|
888
|
+
spinner: "dots"
|
|
889
|
+
}).start();
|
|
890
|
+
try {
|
|
891
|
+
const execCmd = getExecCommand(pm);
|
|
892
|
+
await execa2(execCmd, ["husky", "init"], { cwd, stdio: "pipe" });
|
|
893
|
+
const legacyDir = resolve4(cwd, ".husky/_");
|
|
894
|
+
if (existsSync4(legacyDir)) {
|
|
895
|
+
rmSync(legacyDir, { recursive: true, force: true });
|
|
896
|
+
}
|
|
897
|
+
const commitMsg = `${execCmd} --no-install commitlint --edit "$1"
|
|
898
|
+
`;
|
|
899
|
+
await writeFileContent(resolve4(cwd, ".husky/commit-msg"), commitMsg);
|
|
900
|
+
const hooks = ["commit-msg"];
|
|
901
|
+
const needsPreCommit = features.eslint || features.lintStaged || features.oxlint;
|
|
902
|
+
if (needsPreCommit) {
|
|
903
|
+
const cmds = [];
|
|
904
|
+
if (features.oxlint) {
|
|
905
|
+
cmds.push(`${execCmd} oxlint --max-warnings 0`);
|
|
906
|
+
}
|
|
907
|
+
if (features.lintStaged) {
|
|
908
|
+
cmds.push(`${execCmd} lint-staged`);
|
|
909
|
+
} else if (features.eslint) {
|
|
910
|
+
cmds.push(`${execCmd} eslint . --fix`);
|
|
911
|
+
}
|
|
912
|
+
await writeFileContent(
|
|
913
|
+
resolve4(cwd, ".husky/pre-commit"),
|
|
914
|
+
cmds.join("\n") + "\n"
|
|
915
|
+
);
|
|
916
|
+
hooks.push("pre-commit");
|
|
917
|
+
} else {
|
|
918
|
+
const defaultPreCommit = resolve4(cwd, ".husky/pre-commit");
|
|
919
|
+
if (existsSync4(defaultPreCommit)) {
|
|
920
|
+
unlinkSync(defaultPreCommit);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
spinner.succeed(
|
|
924
|
+
chalk.white("Husky \u521D\u59CB\u5316\u5B8C\u6210 ") + chalk.gray(`(${hooks.join(", ")})`)
|
|
925
|
+
);
|
|
926
|
+
} catch (error) {
|
|
927
|
+
spinner.fail(chalk.red("Husky \u521D\u59CB\u5316\u5931\u8D25"));
|
|
928
|
+
throw error;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
async function addPackageScripts(cwd, pm, features) {
|
|
932
|
+
const spinner = ora({
|
|
933
|
+
text: chalk.gray("\u66F4\u65B0 package.json..."),
|
|
934
|
+
prefixText: " ",
|
|
935
|
+
spinner: "dots"
|
|
936
|
+
}).start();
|
|
937
|
+
try {
|
|
938
|
+
const packageJsonPath = resolve4(cwd, "package.json");
|
|
939
|
+
const packageJson = await readJsonFile(packageJsonPath);
|
|
940
|
+
const scripts = packageJson.scripts || {};
|
|
941
|
+
scripts.cz = "git-cz";
|
|
942
|
+
scripts.prepare = "husky";
|
|
943
|
+
if (features.eslint) {
|
|
944
|
+
scripts.lint = features.oxlint ? "oxlint . --fix -D correctness --ignore-path .gitignore && eslint . --fix" : "eslint . --fix";
|
|
945
|
+
}
|
|
946
|
+
if (features.prettier) {
|
|
947
|
+
scripts.format = "prettier --write src/";
|
|
948
|
+
}
|
|
949
|
+
const czConfig = {
|
|
950
|
+
commitizen: { path: "node_modules/cz-customizable" }
|
|
951
|
+
};
|
|
952
|
+
const updates = { scripts, config: czConfig };
|
|
953
|
+
if (features.lintStaged) {
|
|
954
|
+
updates["lint-staged"] = generateLintStagedConfig({
|
|
955
|
+
eslint: features.eslint,
|
|
956
|
+
oxlint: features.oxlint,
|
|
957
|
+
prettier: features.prettier
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
await updatePackageJson(updates, cwd);
|
|
961
|
+
const parts = ["scripts"];
|
|
962
|
+
if (features.lintStaged) parts.push("lint-staged");
|
|
963
|
+
spinner.succeed(
|
|
964
|
+
chalk.white("package.json \u66F4\u65B0\u5B8C\u6210 ") + chalk.gray(`(${parts.join(" + ")})`)
|
|
965
|
+
);
|
|
966
|
+
} catch (error) {
|
|
967
|
+
spinner.fail(chalk.red("package.json \u66F4\u65B0\u5931\u8D25"));
|
|
968
|
+
throw error;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
function printCompletion(pm, features) {
|
|
972
|
+
console.log();
|
|
973
|
+
console.log(S.LINE);
|
|
974
|
+
console.log(` ${S.OK} ${chalk.green.bold("\u521D\u59CB\u5316\u5B8C\u6210!")}`);
|
|
975
|
+
console.log(S.LINE);
|
|
976
|
+
console.log();
|
|
977
|
+
console.log(` ${chalk.bold("\u5FEB\u901F\u5F00\u59CB:")}`);
|
|
978
|
+
console.log();
|
|
979
|
+
console.log(` ${S.DOT} \u63D0\u4EA4\u4EE3\u7801 ${chalk.cyan(`${pm} run cz`)}`);
|
|
980
|
+
if (features.eslint) {
|
|
981
|
+
console.log(` ${S.DOT} \u68C0\u67E5\u4EE3\u7801 ${chalk.cyan(`${pm} run lint`)}`);
|
|
982
|
+
}
|
|
983
|
+
if (features.prettier) {
|
|
984
|
+
console.log(` ${S.DOT} \u683C\u5F0F\u5316 ${chalk.cyan(`${pm} run format`)}`);
|
|
985
|
+
}
|
|
986
|
+
console.log();
|
|
987
|
+
console.log(
|
|
988
|
+
` ${S.INFO} ${chalk.gray("\u5168\u5C40\u5B89\u88C5 commitizen \u540E\u53EF\u76F4\u63A5\u4F7F\u7528 git cz \u63D0\u4EA4")}`
|
|
989
|
+
);
|
|
990
|
+
console.log(` ${S.DOT} ${chalk.gray(`npm install -g commitizen`)}`);
|
|
991
|
+
console.log();
|
|
992
|
+
console.log(
|
|
993
|
+
` ${S.INFO} ${chalk.gray("\u6240\u6709\u914D\u7F6E\u6587\u4EF6\u5747\u652F\u6301\u8986\u76D6\u6269\u5C55\uFF0C\u8BE6\u89C1 README.md")}`
|
|
994
|
+
);
|
|
995
|
+
console.log();
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
// src/cli/doctor.ts
|
|
999
|
+
import { resolve as resolve5 } from "path";
|
|
1000
|
+
import chalk2 from "chalk";
|
|
1001
|
+
var BRAND2 = "#7C3AED";
|
|
1002
|
+
var S2 = {
|
|
1003
|
+
LOGO: chalk2.hex(BRAND2).bold("[RS]"),
|
|
1004
|
+
OK: chalk2.green("\u2714"),
|
|
1005
|
+
FAIL: chalk2.red("\u2716"),
|
|
1006
|
+
WARN: chalk2.yellow("\u25B2"),
|
|
1007
|
+
SKIP: chalk2.gray("\u25CB"),
|
|
1008
|
+
LINE: chalk2.gray("\u2500".repeat(48))
|
|
1009
|
+
};
|
|
1010
|
+
async function doctor(options = {}) {
|
|
1011
|
+
const cwd = options.cwd || process.cwd();
|
|
1012
|
+
console.log();
|
|
1013
|
+
console.log(S2.LINE);
|
|
1014
|
+
console.log(
|
|
1015
|
+
` ${S2.LOGO} ${chalk2.bold("Robot Standards")} ${chalk2.gray("Doctor")}`
|
|
1016
|
+
);
|
|
1017
|
+
console.log(S2.LINE);
|
|
1018
|
+
console.log();
|
|
1019
|
+
const checks = [];
|
|
1020
|
+
const isGit = isGitRepository(cwd);
|
|
1021
|
+
checks.push({
|
|
1022
|
+
name: "Git \u4ED3\u5E93",
|
|
1023
|
+
status: isGit ? "pass" : "fail",
|
|
1024
|
+
message: isGit ? void 0 : "\u672A\u521D\u59CB\u5316 Git \u4ED3\u5E93\uFF0C\u8FD0\u884C git init"
|
|
1025
|
+
});
|
|
1026
|
+
let packageJson = {};
|
|
1027
|
+
const packageJsonPath = resolve5(cwd, "package.json");
|
|
1028
|
+
const hasPackageJson = fileExists(packageJsonPath);
|
|
1029
|
+
if (hasPackageJson) {
|
|
1030
|
+
try {
|
|
1031
|
+
packageJson = await readJsonFile(packageJsonPath);
|
|
1032
|
+
} catch {
|
|
1033
|
+
}
|
|
1034
|
+
} else {
|
|
1035
|
+
checks.push({
|
|
1036
|
+
name: "package.json",
|
|
1037
|
+
status: "fail",
|
|
1038
|
+
message: "\u7F3A\u5C11 package.json"
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
const allDeps = {
|
|
1042
|
+
...packageJson.dependencies,
|
|
1043
|
+
...packageJson.devDependencies
|
|
1044
|
+
};
|
|
1045
|
+
const hasCommitizen = !!allDeps["commitizen"];
|
|
1046
|
+
const hasCommitlint = !!allDeps["@commitlint/cli"];
|
|
1047
|
+
const hasHusky = !!allDeps["husky"];
|
|
1048
|
+
const hasEslint = !!allDeps["eslint"];
|
|
1049
|
+
const hasLintStaged = !!allDeps["lint-staged"];
|
|
1050
|
+
const hasPrettier = !!allDeps["prettier"];
|
|
1051
|
+
console.log(` ${chalk2.bold("\u6838\u5FC3\u529F\u80FD")}`);
|
|
1052
|
+
console.log();
|
|
1053
|
+
if (hasHusky) {
|
|
1054
|
+
const huskyDir = fileExists(resolve5(cwd, ".husky"));
|
|
1055
|
+
checks.push({
|
|
1056
|
+
name: "Husky \u76EE\u5F55",
|
|
1057
|
+
status: huskyDir ? "pass" : "fail",
|
|
1058
|
+
message: huskyDir ? void 0 : "\u7F3A\u5C11 .husky \u76EE\u5F55"
|
|
1059
|
+
});
|
|
1060
|
+
const commitMsg = fileExists(resolve5(cwd, ".husky/commit-msg"));
|
|
1061
|
+
checks.push({
|
|
1062
|
+
name: "commit-msg hook",
|
|
1063
|
+
status: commitMsg ? "pass" : "fail",
|
|
1064
|
+
message: commitMsg ? void 0 : "\u7F3A\u5C11 commit-msg hook"
|
|
1065
|
+
});
|
|
1066
|
+
} else {
|
|
1067
|
+
checks.push({
|
|
1068
|
+
name: "Husky",
|
|
1069
|
+
status: "fail",
|
|
1070
|
+
message: "\u672A\u5B89\u88C5 husky"
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
if (hasCommitlint) {
|
|
1074
|
+
const hasConfig = fileExists(resolve5(cwd, "commitlint.config.cjs")) || fileExists(resolve5(cwd, "commitlint.config.js")) || fileExists(resolve5(cwd, "commitlint.config.ts"));
|
|
1075
|
+
checks.push({
|
|
1076
|
+
name: "Commitlint \u914D\u7F6E",
|
|
1077
|
+
status: hasConfig ? "pass" : "fail",
|
|
1078
|
+
message: hasConfig ? void 0 : "\u7F3A\u5C11 commitlint.config.*"
|
|
1079
|
+
});
|
|
1080
|
+
} else {
|
|
1081
|
+
checks.push({
|
|
1082
|
+
name: "Commitlint",
|
|
1083
|
+
status: "fail",
|
|
1084
|
+
message: "\u672A\u5B89\u88C5 @commitlint/cli"
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
if (hasCommitizen) {
|
|
1088
|
+
const hasCzConfig = fileExists(resolve5(cwd, ".cz-config.cjs")) || fileExists(resolve5(cwd, ".cz-config.js"));
|
|
1089
|
+
checks.push({
|
|
1090
|
+
name: "Commitizen \u914D\u7F6E",
|
|
1091
|
+
status: hasCzConfig ? "pass" : "fail",
|
|
1092
|
+
message: hasCzConfig ? void 0 : "\u7F3A\u5C11 .cz-config.*"
|
|
1093
|
+
});
|
|
1094
|
+
const hasCommitizenPath = !!packageJson.config?.commitizen;
|
|
1095
|
+
checks.push({
|
|
1096
|
+
name: "commitizen path \u914D\u7F6E",
|
|
1097
|
+
status: hasCommitizenPath ? "pass" : "fail",
|
|
1098
|
+
message: hasCommitizenPath ? void 0 : "package.json \u4E2D\u7F3A\u5C11 config.commitizen"
|
|
1099
|
+
});
|
|
1100
|
+
} else {
|
|
1101
|
+
checks.push({
|
|
1102
|
+
name: "Commitizen",
|
|
1103
|
+
status: "fail",
|
|
1104
|
+
message: "\u672A\u5B89\u88C5 commitizen"
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
const hasCzScript = !!packageJson.scripts?.cz;
|
|
1108
|
+
checks.push({
|
|
1109
|
+
name: "cz \u811A\u672C",
|
|
1110
|
+
status: hasCzScript ? "pass" : "fail",
|
|
1111
|
+
message: hasCzScript ? void 0 : "\u7F3A\u5C11 cz \u811A\u672C (bun run cz)"
|
|
1112
|
+
});
|
|
1113
|
+
const coreChecks = checks.slice();
|
|
1114
|
+
for (const check of coreChecks) {
|
|
1115
|
+
printCheck(check);
|
|
1116
|
+
}
|
|
1117
|
+
const extraChecks = [];
|
|
1118
|
+
if (hasEslint) {
|
|
1119
|
+
console.log();
|
|
1120
|
+
console.log(` ${chalk2.bold("\u4EE3\u7801\u68C0\u67E5")}`);
|
|
1121
|
+
console.log();
|
|
1122
|
+
const hasEslintConfig = fileExists(resolve5(cwd, "eslint.config.ts")) || fileExists(resolve5(cwd, "eslint.config.js")) || fileExists(resolve5(cwd, "eslint.config.mjs"));
|
|
1123
|
+
const eslintCheck = {
|
|
1124
|
+
name: "ESLint \u914D\u7F6E",
|
|
1125
|
+
status: hasEslintConfig ? "pass" : "fail",
|
|
1126
|
+
message: hasEslintConfig ? void 0 : "\u7F3A\u5C11 eslint.config.*"
|
|
1127
|
+
};
|
|
1128
|
+
extraChecks.push(eslintCheck);
|
|
1129
|
+
printCheck(eslintCheck);
|
|
1130
|
+
if (hasHusky) {
|
|
1131
|
+
const preCommit = fileExists(resolve5(cwd, ".husky/pre-commit"));
|
|
1132
|
+
const preCommitCheck = {
|
|
1133
|
+
name: "pre-commit hook",
|
|
1134
|
+
status: preCommit ? "pass" : "fail",
|
|
1135
|
+
message: preCommit ? void 0 : "\u7F3A\u5C11 pre-commit hook"
|
|
1136
|
+
};
|
|
1137
|
+
extraChecks.push(preCommitCheck);
|
|
1138
|
+
printCheck(preCommitCheck);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
if (hasLintStaged) {
|
|
1142
|
+
const lintStagedConfig = !!packageJson["lint-staged"];
|
|
1143
|
+
const lintStagedCheck = {
|
|
1144
|
+
name: "lint-staged \u914D\u7F6E",
|
|
1145
|
+
status: lintStagedConfig ? "pass" : "fail",
|
|
1146
|
+
message: lintStagedConfig ? void 0 : "package.json \u4E2D\u7F3A\u5C11 lint-staged \u914D\u7F6E"
|
|
1147
|
+
};
|
|
1148
|
+
extraChecks.push(lintStagedCheck);
|
|
1149
|
+
printCheck(lintStagedCheck);
|
|
1150
|
+
}
|
|
1151
|
+
if (hasPrettier) {
|
|
1152
|
+
console.log();
|
|
1153
|
+
console.log(` ${chalk2.bold("\u4EE3\u7801\u683C\u5F0F\u5316")}`);
|
|
1154
|
+
console.log();
|
|
1155
|
+
const hasPrettierConfig = fileExists(resolve5(cwd, ".prettierrc.cjs")) || fileExists(resolve5(cwd, ".prettierrc.js")) || fileExists(resolve5(cwd, ".prettierrc.json")) || fileExists(resolve5(cwd, ".prettierrc"));
|
|
1156
|
+
const prettierCheck = {
|
|
1157
|
+
name: "Prettier \u914D\u7F6E",
|
|
1158
|
+
status: hasPrettierConfig ? "pass" : "fail",
|
|
1159
|
+
message: hasPrettierConfig ? void 0 : "\u7F3A\u5C11 .prettierrc.*"
|
|
1160
|
+
};
|
|
1161
|
+
extraChecks.push(prettierCheck);
|
|
1162
|
+
printCheck(prettierCheck);
|
|
1163
|
+
}
|
|
1164
|
+
const hasEditorConfig = fileExists(resolve5(cwd, ".editorconfig"));
|
|
1165
|
+
if (hasEditorConfig) {
|
|
1166
|
+
}
|
|
1167
|
+
const notInstalled = [];
|
|
1168
|
+
if (!hasEslint) notInstalled.push("ESLint");
|
|
1169
|
+
if (!hasLintStaged) notInstalled.push("lint-staged");
|
|
1170
|
+
if (!hasPrettier) notInstalled.push("Prettier");
|
|
1171
|
+
if (!hasEditorConfig) notInstalled.push("EditorConfig");
|
|
1172
|
+
if (notInstalled.length > 0) {
|
|
1173
|
+
console.log();
|
|
1174
|
+
console.log(` ${chalk2.bold("\u672A\u542F\u7528\u7684\u529F\u80FD")}`);
|
|
1175
|
+
console.log();
|
|
1176
|
+
for (const name of notInstalled) {
|
|
1177
|
+
console.log(` ${S2.SKIP} ${chalk2.gray(name)}`);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
const allChecks = [...coreChecks, ...extraChecks];
|
|
1181
|
+
const passedCount = allChecks.filter((c) => c.status === "pass").length;
|
|
1182
|
+
const failedCount = allChecks.filter((c) => c.status === "fail").length;
|
|
1183
|
+
console.log();
|
|
1184
|
+
console.log(S2.LINE);
|
|
1185
|
+
console.log(
|
|
1186
|
+
` ${chalk2.bold("\u603B\u8BA1:")} ${chalk2.green(`${passedCount} \u901A\u8FC7`)} ${failedCount > 0 ? chalk2.red(`${failedCount} \u5931\u8D25`) : chalk2.gray("0 \u5931\u8D25")}`
|
|
1187
|
+
);
|
|
1188
|
+
if (failedCount > 0) {
|
|
1189
|
+
console.log();
|
|
1190
|
+
console.log(
|
|
1191
|
+
` ${S2.WARN} ${chalk2.yellow("\u8FD0\u884C")} ${chalk2.cyan(
|
|
1192
|
+
"robot-standards init"
|
|
1193
|
+
)} ${chalk2.yellow("\u4FEE\u590D\u95EE\u9898")}`
|
|
1194
|
+
);
|
|
1195
|
+
} else {
|
|
1196
|
+
console.log();
|
|
1197
|
+
console.log(` ${S2.OK} ${chalk2.green("\u6240\u6709\u68C0\u67E5\u901A\u8FC7!")}`);
|
|
1198
|
+
}
|
|
1199
|
+
console.log(S2.LINE);
|
|
1200
|
+
console.log();
|
|
1201
|
+
return failedCount === 0;
|
|
1202
|
+
}
|
|
1203
|
+
function printCheck(check) {
|
|
1204
|
+
const icon = check.status === "pass" ? S2.OK : check.status === "fail" ? S2.FAIL : S2.SKIP;
|
|
1205
|
+
console.log(` ${icon} ${check.name}`);
|
|
1206
|
+
if (check.message && check.status === "fail") {
|
|
1207
|
+
console.log(` ${chalk2.gray(check.message)}`);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
export {
|
|
1211
|
+
createLintStagedConfig,
|
|
1212
|
+
detectPackageManager,
|
|
1213
|
+
doctor,
|
|
1214
|
+
fileExists,
|
|
1215
|
+
generateLintStagedConfig,
|
|
1216
|
+
getExecCommand,
|
|
1217
|
+
getInstallCommand,
|
|
1218
|
+
getPackageManagerName,
|
|
1219
|
+
init,
|
|
1220
|
+
initGitRepository,
|
|
1221
|
+
isGitRepository,
|
|
1222
|
+
readFileContent,
|
|
1223
|
+
readJsonFile,
|
|
1224
|
+
updatePackageJson,
|
|
1225
|
+
writeFileContent,
|
|
1226
|
+
writeJsonFile
|
|
1227
|
+
};
|
|
1228
|
+
//# sourceMappingURL=index.js.map
|