Skip to content

Commit 690228e

Browse files
committed
🔧 chore(feature): 增加 script 命令
1 parent 148c120 commit 690228e

File tree

10 files changed

+191
-53
lines changed

10 files changed

+191
-53
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,26 @@ import { impSort } from "../src/index";
374374
```
375375

376376
PS: 依赖 `eslint` API 模式, 依赖 `simple-import-sort` 插件的同时依旧会读取项目配置的 `.eslintignore``.eslintrc.json` 文件.
377+
378+
## script 命令
379+
380+
代理运行 `package.scripts` 脚本, 仅支持询问模式;
381+
382+
### 询问模式
383+
384+
```bash
385+
# 启动询问模式
386+
codeg script
387+
```
388+
389+
```
390+
# 询问过程
391+
392+
1. 请选择项目运行脚本
393+
```
394+
395+
PS: 第一次使用 `script` 命令会初始化 `scripts.config.json`, 可以为它增加对应的描述, 以后每次使用均会同步 `package.scripts` 的变化.
396+
377397
## 其他命令
378398

379399
| 命令 | 参数 | 默认值 | 功能描述 |

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@
4343
"node": ">=14.17"
4444
},
4545
"scripts": {
46-
"prepare": "npx esno scripts/prepare.ts",
47-
"build": "npx unbuild",
48-
"stub": "npx unbuild --stub",
49-
"release": "npx release-it"
46+
"prepare": "esno scripts/prepare.ts",
47+
"build": "unbuild",
48+
"stub": "unbuild --stub",
49+
"release": "release-it"
5050
},
5151
"keywords": [
5252
"CodeGenius",

scripts.config.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"scripts": [
3+
{
4+
"cmd": "prepare",
5+
"script": "esno scripts/prepare.ts",
6+
"desc": "预执行脚本, 用来初始化 hooks 等配置"
7+
},
8+
{
9+
"cmd": "build",
10+
"script": "unbuild",
11+
"desc": "使用 unbuild 构建项目, 输出到 dist 目录"
12+
},
13+
{
14+
"cmd": "stub",
15+
"script": "unbuild --stub",
16+
"desc": "使用 unbuild 软构建项目, 方便调试"
17+
},
18+
{
19+
"cmd": "release",
20+
"script": "release-it",
21+
"desc": "发布项目到 npm 仓库, 并推送 Github"
22+
}
23+
]
24+
}

src/command/npm-run.ts

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/command/root.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export const root = async () => {
2424
{
2525
name: "command",
2626
type: "select",
27-
message: "请选择正确执行的 CodeG 命令",
27+
message: "请选择待执行的 CodeG 命令",
2828
choices: commandChoices,
2929
},
3030
]);

src/command/script.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import path from "node:path";
2+
3+
import type { CAC } from "cac";
4+
import enquirer from "enquirer";
5+
import { readJsonSync } from "fs-extra";
6+
7+
import { generateScripts } from "@/helper";
8+
import { execCommand } from "@/helper";
9+
import { CommandOptions } from "@/types";
10+
11+
export async function scriptRun() {
12+
const { scripts } = readJsonSync(
13+
path.join(process.cwd(), "scripts.config.json"),
14+
);
15+
16+
const scriptChoices = scripts.map((script: CommandOptions) => {
17+
const formatCmd = `${script.cmd}`.padEnd(15);
18+
return {
19+
name: script.script,
20+
message: `${formatCmd} ${script.desc}`,
21+
};
22+
});
23+
24+
const result = await enquirer.prompt<{ script: string }>([
25+
{
26+
name: "script",
27+
type: "select",
28+
message: "请选择项目运行脚本",
29+
choices: scriptChoices,
30+
},
31+
]);
32+
33+
if (result.script) {
34+
const script = result.script;
35+
if (script.startsWith("npx")) {
36+
const cmd = script.split(" ")[0];
37+
const args = script.split(" ").slice(1);
38+
execCommand(cmd, args, { stdio: "inherit" });
39+
} else {
40+
execCommand("npx", script.split(" "), { stdio: "inherit" });
41+
}
42+
}
43+
}
44+
45+
export default function scriptRunInstaller(cli: CAC) {
46+
return {
47+
name: "scriptRunInstaller",
48+
setup: () => {
49+
cli
50+
.command("script", "代理运行 package.scripts 脚本")
51+
.action(async () => {
52+
await generateScripts();
53+
await scriptRun();
54+
});
55+
},
56+
};
57+
}

src/config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ export const commands = [
250250
command: "quantity",
251251
description: "运行 cloc 分析并统计代码量",
252252
},
253+
{
254+
command: "script",
255+
description: "代理执行 package.scripts 脚本",
256+
},
253257
{
254258
display: "help",
255259
command: "--help",

src/helper.ts

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ import boxen from "boxen";
66
import { CAC } from "cac";
77
import type { Options } from "execa";
88
import execa from "execa";
9+
import fsExtra from "fs-extra";
910
import { gray, green, red, yellow } from "kolorist";
1011

1112
import { ACTIVATION, FRAMEWORKS, TEMPLATES } from "@/config";
1213

13-
import { CodeGeniusOptions } from "./types";
14+
import { CodeGeniusOptions, CommandOptions } from "./types";
1415

1516
const boxenBorderStyle = {
1617
padding: 1,
@@ -291,9 +292,69 @@ export function generateRandom(length: number) {
291292
export const defineConfig = (config: CodeGeniusOptions): CodeGeniusOptions =>
292293
config;
293294

294-
export function cmdInstaller(cli: CAC, config: CodeGeniusOptions) {
295+
export async function cmdInstaller(cli: CAC, config: CodeGeniusOptions) {
295296
const { plugins } = config;
296297
for (const plugin of plugins) {
297298
plugin(cli).setup();
298299
}
299300
}
301+
302+
export function genScriptConfig(scripts: { [key: string]: string }) {
303+
return Object.keys(scripts).map((key) => {
304+
return {
305+
cmd: key,
306+
script: scripts[key],
307+
desc: "describe the function of this cmd command",
308+
};
309+
});
310+
}
311+
312+
export function syncScripts(
313+
pkgScripts: Array<CommandOptions>,
314+
configScripts: Array<CommandOptions>,
315+
) {
316+
const mergedScripts = [...configScripts];
317+
318+
for (const pkgScript of pkgScripts) {
319+
const configScript = mergedScripts.find(
320+
(itemB) => itemB.cmd === pkgScript.cmd,
321+
);
322+
323+
if (configScript) {
324+
if (configScript.script !== pkgScript.script) {
325+
configScript.script = pkgScript.script;
326+
}
327+
} else {
328+
mergedScripts.push(pkgScript);
329+
}
330+
}
331+
332+
const syncScripts = mergedScripts.filter((configScript) => {
333+
return pkgScripts.find((i) => i.cmd === configScript.cmd);
334+
});
335+
336+
return syncScripts;
337+
}
338+
339+
export const generateScripts = async () => {
340+
const pkg = await fsExtra.readJSONSync(
341+
path.join(process.cwd(), "package.json"),
342+
);
343+
let configContent = genScriptConfig(pkg.scripts);
344+
const configfile = path.join(process.cwd(), "scripts.config.json");
345+
if (fs.existsSync(configfile)) {
346+
const { scripts } = await fsExtra.readJSONSync(configfile);
347+
configContent = syncScripts(configContent, scripts);
348+
}
349+
await fsExtra.outputFileSync(
350+
configfile,
351+
JSON.stringify(
352+
{
353+
scripts: configContent,
354+
},
355+
null,
356+
2,
357+
),
358+
);
359+
printInfo("代理脚本 scripts.config.json 已完成同步");
360+
};

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import prettierFormatInstaller, {
2525
} from "@/command/prettier-format";
2626
import quantityInstaller, { quantity } from "@/command/quantity";
2727
import rootInstaller, { root } from "@/command/root";
28+
import scriptRunInstaller from "@/command/script";
2829
import templateInstaller, { template } from "@/command/template";
2930
import { defineConfig } from "@/helper";
3031

@@ -45,6 +46,7 @@ const config = defineConfig({
4546
templateInstaller,
4647
lighthouseInstaller,
4748
quantityInstaller,
49+
scriptRunInstaller,
4850
],
4951
});
5052

src/types.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,19 @@ export interface ImpSortOptions {
8181
export interface RegistryOptions {
8282
url: string;
8383
}
84+
85+
export type CommandOptions = {
86+
/**
87+
* 指令
88+
*/
89+
cmd: string;
90+
/**
91+
* 要执行的脚本
92+
*/
93+
script: string;
94+
95+
/**
96+
* 描述
97+
*/
98+
desc: string;
99+
};

0 commit comments

Comments
 (0)