snapshot-checker 0.1.1

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.
Files changed (70) hide show
  1. package/README.md +283 -0
  2. package/dist/commands/context_demo.d.ts +18 -0
  3. package/dist/commands/context_demo.d.ts.map +1 -0
  4. package/dist/commands/context_demo.js +68 -0
  5. package/dist/commands/context_demo.js.map +1 -0
  6. package/dist/commands/forkall.d.ts +54 -0
  7. package/dist/commands/forkall.d.ts.map +1 -0
  8. package/dist/commands/forkall.js +192 -0
  9. package/dist/commands/forkall.js.map +1 -0
  10. package/dist/commands/mac-example.d.ts +23 -0
  11. package/dist/commands/mac-example.d.ts.map +1 -0
  12. package/dist/commands/mac-example.js +39 -0
  13. package/dist/commands/mac-example.js.map +1 -0
  14. package/dist/commands/timeout_demo.d.ts +5 -0
  15. package/dist/commands/timeout_demo.d.ts.map +1 -0
  16. package/dist/commands/timeout_demo.js +48 -0
  17. package/dist/commands/timeout_demo.js.map +1 -0
  18. package/dist/src/cli.d.ts +3 -0
  19. package/dist/src/cli.d.ts.map +1 -0
  20. package/dist/src/cli.js +215 -0
  21. package/dist/src/cli.js.map +1 -0
  22. package/dist/src/executor.d.ts +8 -0
  23. package/dist/src/executor.d.ts.map +1 -0
  24. package/dist/src/executor.js +6 -0
  25. package/dist/src/executor.js.map +1 -0
  26. package/dist/src/groupSpecs.d.ts +7 -0
  27. package/dist/src/groupSpecs.d.ts.map +1 -0
  28. package/dist/src/groupSpecs.js +19 -0
  29. package/dist/src/groupSpecs.js.map +1 -0
  30. package/dist/src/index.d.ts +6 -0
  31. package/dist/src/index.d.ts.map +1 -0
  32. package/dist/src/index.js +5 -0
  33. package/dist/src/index.js.map +1 -0
  34. package/dist/src/lib/programmatic.d.ts +48 -0
  35. package/dist/src/lib/programmatic.d.ts.map +1 -0
  36. package/dist/src/lib/programmatic.js +62 -0
  37. package/dist/src/lib/programmatic.js.map +1 -0
  38. package/dist/src/runCommand.d.ts +67 -0
  39. package/dist/src/runCommand.d.ts.map +1 -0
  40. package/dist/src/runCommand.js +286 -0
  41. package/dist/src/runCommand.js.map +1 -0
  42. package/dist/src/runGroups.d.ts +36 -0
  43. package/dist/src/runGroups.d.ts.map +1 -0
  44. package/dist/src/runGroups.js +123 -0
  45. package/dist/src/runGroups.js.map +1 -0
  46. package/dist/src/runners/builtinFunctionRunner.d.ts +7 -0
  47. package/dist/src/runners/builtinFunctionRunner.d.ts.map +1 -0
  48. package/dist/src/runners/builtinFunctionRunner.js +56 -0
  49. package/dist/src/runners/builtinFunctionRunner.js.map +1 -0
  50. package/dist/src/runners/embedRunner.d.ts +7 -0
  51. package/dist/src/runners/embedRunner.d.ts.map +1 -0
  52. package/dist/src/runners/embedRunner.js +129 -0
  53. package/dist/src/runners/embedRunner.js.map +1 -0
  54. package/dist/src/runners/index.d.ts +5 -0
  55. package/dist/src/runners/index.d.ts.map +1 -0
  56. package/dist/src/runners/index.js +4 -0
  57. package/dist/src/runners/index.js.map +1 -0
  58. package/dist/src/runners/shellRunner.d.ts +8 -0
  59. package/dist/src/runners/shellRunner.d.ts.map +1 -0
  60. package/dist/src/runners/shellRunner.js +142 -0
  61. package/dist/src/runners/shellRunner.js.map +1 -0
  62. package/dist/src/runners/types.d.ts +13 -0
  63. package/dist/src/runners/types.d.ts.map +1 -0
  64. package/dist/src/runners/types.js +2 -0
  65. package/dist/src/runners/types.js.map +1 -0
  66. package/dist/src/types.d.ts +122 -0
  67. package/dist/src/types.d.ts.map +1 -0
  68. package/dist/src/types.js +32 -0
  69. package/dist/src/types.js.map +1 -0
  70. package/package.json +55 -0
@@ -0,0 +1,286 @@
1
+ /**
2
+ * 单条命令执行模块:执行单条或按顺序执行多条命令,不涉及 group 概念。
3
+ * 命令执行失败的判断(Mac / Linux / Windows 通用):
4
+ * - 进程正常退出:exitCode === 0 为成功,否则为失败
5
+ * - 进程被信号终止(Unix):code 为 null,视为失败
6
+ * - spawn 报错(如找不到命令):视为失败
7
+ */
8
+ import { spawn } from 'node:child_process';
9
+ import { platform } from 'node:os';
10
+ import { CommandKind, getCurrentPlatformKind } from './types.js';
11
+ import { BuiltinFunctionCommandRunner, EmbedCommandRunner, ShellCommandRunner, } from './runners/index.js';
12
+ const currentPlatform = platform();
13
+ /** 当前系统是否支持该命令类型:embed 全平台;linux/mac/windows 仅对应平台 */
14
+ export function isSupportedOnCurrentPlatform(cmd) {
15
+ if (cmd.kind === CommandKind.Embed || cmd.kind === CommandKind.BuiltinFunction)
16
+ return true;
17
+ const current = getCurrentPlatformKind();
18
+ return cmd.kind === current;
19
+ }
20
+ const commandRunners = [
21
+ new EmbedCommandRunner(),
22
+ new BuiltinFunctionCommandRunner(),
23
+ new ShellCommandRunner(),
24
+ ];
25
+ function getCommandRunner(cmd) {
26
+ return commandRunners.find((runner) => runner.canRun(cmd));
27
+ }
28
+ /** 执行单条命令 */
29
+ export async function executeOne(cmd, options = {}) {
30
+ const { streamOutput = true, registerBackgroundProcess, commandContext } = options;
31
+ const start = Date.now();
32
+ const runner = getCommandRunner(cmd);
33
+ if (!runner) {
34
+ return {
35
+ kind: cmd.kind,
36
+ description: cmd.description ?? '',
37
+ success: false,
38
+ exitCode: null,
39
+ stdout: '',
40
+ stderr: `未找到可处理 kind=${cmd.kind} 的 CommandRunner`,
41
+ durationMs: Date.now() - start,
42
+ };
43
+ }
44
+ return runner.execute(cmd, {
45
+ streamOutput,
46
+ registerBackgroundProcess,
47
+ commandContext: commandContext ?? {},
48
+ start,
49
+ });
50
+ }
51
+ /**
52
+ * 将字符串中的 {{varName}} 占位符替换为上下文中的变量值。
53
+ * 未找到变量时保留原占位符,便于排查。
54
+ */
55
+ function expandTemplate(str, context) {
56
+ return str.replace(/\{\{(\w+)\}\}/g, (match, key) => {
57
+ if (Object.prototype.hasOwnProperty.call(context, key)) {
58
+ return context[key] ?? '';
59
+ }
60
+ return match;
61
+ });
62
+ }
63
+ /**
64
+ * 基于当前上下文,对命令中的各个字符串字段进行变量展开。
65
+ * - run / file / args / cwd / description 支持 {{var}} 占位符。
66
+ */
67
+ function applyContextToCommand(cmd, context) {
68
+ const next = { ...cmd };
69
+ if (next.run != null) {
70
+ next.run = expandTemplate(next.run, context);
71
+ }
72
+ if (next.file != null) {
73
+ next.file = expandTemplate(next.file, context);
74
+ }
75
+ if (next.cwd != null) {
76
+ next.cwd = expandTemplate(next.cwd, context);
77
+ }
78
+ if (next.description != null) {
79
+ next.description = expandTemplate(next.description, context);
80
+ }
81
+ if (Array.isArray(next.args)) {
82
+ next.args = next.args.map((arg) => expandTemplate(arg, context));
83
+ }
84
+ return next;
85
+ }
86
+ /**
87
+ * 根据 captureToVar 配置,从命令执行结果中提取变量值并写入上下文。
88
+ */
89
+ function applyCaptureToContext(capture, result, context) {
90
+ if (!capture)
91
+ return;
92
+ if (!result.success)
93
+ return;
94
+ const from = capture.from ?? 'stdout';
95
+ const source = from === 'stderr' ? result.stderr : result.stdout;
96
+ const trimmed = source.trim();
97
+ if (!trimmed)
98
+ return;
99
+ let value;
100
+ if (capture.pattern) {
101
+ let match = null;
102
+ try {
103
+ const re = new RegExp(capture.pattern, 'm');
104
+ match = re.exec(trimmed);
105
+ }
106
+ catch {
107
+ // 正则不合法时直接跳过,不影响后续命令执行
108
+ return;
109
+ }
110
+ if (!match)
111
+ return;
112
+ const groupIndex = capture.groupIndex ?? 1;
113
+ if (groupIndex < match.length) {
114
+ value = match[groupIndex];
115
+ }
116
+ }
117
+ else {
118
+ value = trimmed;
119
+ }
120
+ if (value !== undefined) {
121
+ context[capture.name] = value;
122
+ }
123
+ }
124
+ const SIGTERM_WAIT_MS = 3000;
125
+ function forceKillProcessTreeOnWindows(pid) {
126
+ return new Promise((resolve) => {
127
+ const killer = spawn('taskkill', ['/PID', String(pid), '/T', '/F'], {
128
+ shell: false,
129
+ stdio: 'ignore',
130
+ });
131
+ killer.once('close', () => resolve());
132
+ killer.once('error', () => resolve());
133
+ });
134
+ }
135
+ async function terminateChildProcess(child) {
136
+ const pid = child.pid;
137
+ if (pid == null)
138
+ return;
139
+ if (currentPlatform === 'win32') {
140
+ await forceKillProcessTreeOnWindows(pid);
141
+ return;
142
+ }
143
+ try {
144
+ child.kill('SIGTERM');
145
+ }
146
+ catch {
147
+ try {
148
+ child.kill('SIGKILL');
149
+ }
150
+ catch {
151
+ /* ignore */
152
+ }
153
+ }
154
+ }
155
+ async function forceKillChildProcess(child) {
156
+ const pid = child.pid;
157
+ if (pid == null)
158
+ return;
159
+ if (currentPlatform === 'win32') {
160
+ await forceKillProcessTreeOnWindows(pid);
161
+ return;
162
+ }
163
+ try {
164
+ child.kill('SIGKILL');
165
+ }
166
+ catch {
167
+ /* ignore */
168
+ }
169
+ }
170
+ /** 优雅结束后台进程:先 SIGTERM,等待一段时间后未退出则 SIGKILL */
171
+ async function gracefulKillBackground(children) {
172
+ if (children.length === 0)
173
+ return Promise.resolve();
174
+ await Promise.all(children.map((child) => terminateChildProcess(child)));
175
+ await Promise.race([
176
+ Promise.all(children.map((c) => new Promise((resolve) => {
177
+ const done = () => {
178
+ c.removeAllListeners('exit');
179
+ resolve();
180
+ };
181
+ c.once('exit', done);
182
+ if (c.exitCode != null)
183
+ done();
184
+ }))),
185
+ new Promise((resolve) => setTimeout(resolve, SIGTERM_WAIT_MS)),
186
+ ]);
187
+ await Promise.all(children.map((child) => forceKillChildProcess(child)));
188
+ }
189
+ /** 等待若干子进程自然退出(已退出的立即完成) */
190
+ function waitForBackgroundProcesses(children) {
191
+ return Promise.all(children.map((c) => new Promise((resolve) => {
192
+ if (c.exitCode !== null || c.signalCode !== null) {
193
+ resolve();
194
+ return;
195
+ }
196
+ c.once('exit', () => resolve());
197
+ c.once('error', () => resolve());
198
+ }))).then(() => { });
199
+ }
200
+ /**
201
+ * 前台命令链结束后对后台子进程收尾:wait 为 true 则等到全部退出,否则优雅 kill。
202
+ */
203
+ export async function finalizeBackgroundProcesses(children, wait, silent) {
204
+ if (children.length === 0)
205
+ return;
206
+ if (wait) {
207
+ if (!silent) {
208
+ console.log(`\n等待 ${children.length} 个后台进程全部结束后退出...`);
209
+ }
210
+ await waitForBackgroundProcesses(children);
211
+ if (!silent) {
212
+ console.log('所有后台进程已结束。\n');
213
+ }
214
+ }
215
+ else {
216
+ if (!silent) {
217
+ console.log(`\n正在结束 ${children.length} 个后台进程...`);
218
+ }
219
+ await gracefulKillBackground(children);
220
+ }
221
+ }
222
+ /** 按顺序执行多条命令(无组间间隔)。失败判断见 executeOne,支持 Mac/Linux/Windows。 */
223
+ export async function executeAll(commands, options = {}) {
224
+ const { stopOnError = false, silent = false, streamOutput = !silent, offset = 0, total: explicitTotal, aggregateBackgroundChildren, waitForBackground = false, commandContext: sharedContext, } = options;
225
+ const results = [];
226
+ const context = sharedContext ?? {};
227
+ const localBackgroundChildren = [];
228
+ const backgroundTarget = aggregateBackgroundChildren ?? localBackgroundChildren;
229
+ const total = explicitTotal ?? commands.length + offset;
230
+ const getDescriptionForLog = (cmd) => {
231
+ if (cmd.description)
232
+ return cmd.description;
233
+ if (cmd.func)
234
+ return cmd.func.name || 'builtin-function';
235
+ if (cmd.run != null)
236
+ return cmd.run;
237
+ if (cmd.file)
238
+ return [cmd.file, ...(cmd.args ?? [])].join(' ');
239
+ return '';
240
+ };
241
+ const registerBackground = (cmd) => (child) => {
242
+ backgroundTarget.push(child);
243
+ };
244
+ for (let index = 0; index < commands.length; index++) {
245
+ const originalCmd = commands[index];
246
+ const cmd = applyContextToCommand(originalCmd, context);
247
+ const cur = offset + index + 1;
248
+ const all = total;
249
+ if (!silent) {
250
+ const suffix = cmd.background ? ' (后台)' : '';
251
+ console.log(`\n▶ (${cur}/${all}) [${cmd.kind}] ${getDescriptionForLog(cmd)}${suffix}`);
252
+ }
253
+ const result = await executeOne(cmd, {
254
+ streamOutput,
255
+ registerBackgroundProcess: cmd.background ? registerBackground(cmd) : undefined,
256
+ commandContext: context,
257
+ });
258
+ results.push(result);
259
+ applyCaptureToContext(originalCmd.captureToVar, result, context);
260
+ if (!silent) {
261
+ if (!streamOutput) {
262
+ if (result.stdout)
263
+ console.log(result.stdout);
264
+ if (result.stderr)
265
+ console.error(result.stderr);
266
+ }
267
+ if (cmd.background) {
268
+ console.log(` 已放入后台执行`);
269
+ }
270
+ else {
271
+ console.log(` 退出码: ${result.exitCode}, 耗时: ${result.durationMs}ms`);
272
+ }
273
+ }
274
+ if (!result.success && stopOnError) {
275
+ if (!silent)
276
+ console.error(`命令失败,已停止。`);
277
+ break;
278
+ }
279
+ }
280
+ // 由调用方聚合后台进程时,不在此处置;否则本批次结束后统一收尾
281
+ if (!aggregateBackgroundChildren && localBackgroundChildren.length > 0) {
282
+ await finalizeBackgroundProcesses(localBackgroundChildren, waitForBackground, silent);
283
+ }
284
+ return results;
285
+ }
286
+ //# sourceMappingURL=runCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runCommand.js","sourceRoot":"","sources":["../../src/runCommand.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { CommandDef, CommandResult, Groups, RunOptions } from './types.js';
2
+ /** 组名 + 执行次数 */
3
+ export interface GroupSpec {
4
+ name: string;
5
+ repeat: number;
6
+ }
7
+ /** 根据组配置与组名顺序,得到要执行的命令列表(默认仅包含当前系统支持的命令) */
8
+ export declare function getCommandsToRun(groups: Groups, groupOrder: string[], options?: {
9
+ ignorePlatform?: boolean;
10
+ }): CommandDef[];
11
+ /**
12
+ * 根据组配置与「组名:次数」规格,得到要执行的命令列表(默认仅包含当前系统支持的命令)。
13
+ * 每组按 repeat 重复若干次后再接下一组。
14
+ */
15
+ export declare function getCommandsToRunWithRepeat(groups: Groups, specs: GroupSpec[], options?: {
16
+ ignorePlatform?: boolean;
17
+ }): CommandDef[];
18
+ /**
19
+ * 将组规格展开为「块」数组:每一块为一次组执行(一组命令的一轮),
20
+ * 用于在块与块之间插入间隔(对重复执行的 group 也生效)。
21
+ */
22
+ export declare function getGroupChunks(groups: Groups, specs: GroupSpec[], options?: {
23
+ ignorePlatform?: boolean;
24
+ }): CommandDef[][];
25
+ export interface RunGroupChunksOptions extends RunOptions {
26
+ /** 每组命令之间的执行间隔(毫秒),0 或无则不间隔 */
27
+ intervalMs?: number;
28
+ }
29
+ /**
30
+ * 按块顺序执行:每块内顺序执行命令,块与块之间可选间隔(对重复执行的 group 也生效)。
31
+ */
32
+ export declare function runGroupChunks(chunks: CommandDef[][], options?: RunGroupChunksOptions): Promise<{
33
+ results: CommandResult[];
34
+ failed: boolean;
35
+ }>;
36
+ //# sourceMappingURL=runGroups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runGroups.d.ts","sourceRoot":"","sources":["../../src/runGroups.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,UAAU,EACV,aAAa,EACb,MAAM,EACN,UAAU,EACX,MAAM,YAAY,CAAC;AAcpB,gBAAgB;AAChB,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4CAA4C;AAC5C,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GACzC,UAAU,EAAE,CAMd;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GACzC,UAAU,EAAE,CAad;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GACzC,UAAU,EAAE,EAAE,CAahB;AAMD,MAAM,WAAW,qBAAsB,SAAQ,UAAU;IACvD,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAAE,EAAE,EACtB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC;IAAE,OAAO,EAAE,aAAa,EAAE,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC,CAoExD"}
@@ -0,0 +1,123 @@
1
+ import { isSupportedOnCurrentPlatform } from './runCommand.js';
2
+ import { executeAll, finalizeBackgroundProcesses } from './runCommand.js';
3
+ function withSignalHandler(signal, handler) {
4
+ process.on(signal, handler);
5
+ return () => process.off(signal, handler);
6
+ }
7
+ /** 根据组配置与组名顺序,得到要执行的命令列表(默认仅包含当前系统支持的命令) */
8
+ export function getCommandsToRun(groups, groupOrder, options = {}) {
9
+ return getCommandsToRunWithRepeat(groups, groupOrder.map((name) => ({ name, repeat: 1 })), options);
10
+ }
11
+ /**
12
+ * 根据组配置与「组名:次数」规格,得到要执行的命令列表(默认仅包含当前系统支持的命令)。
13
+ * 每组按 repeat 重复若干次后再接下一组。
14
+ */
15
+ export function getCommandsToRunWithRepeat(groups, specs, options = {}) {
16
+ const { ignorePlatform = false } = options;
17
+ const list = [];
18
+ for (const { name, repeat } of specs) {
19
+ const cmds = groups[name];
20
+ if (!cmds)
21
+ continue;
22
+ const supported = ignorePlatform ? cmds : cmds.filter((c) => isSupportedOnCurrentPlatform(c));
23
+ const n = Math.max(1, repeat);
24
+ for (let i = 0; i < n; i++) {
25
+ list.push(...supported);
26
+ }
27
+ }
28
+ return list;
29
+ }
30
+ /**
31
+ * 将组规格展开为「块」数组:每一块为一次组执行(一组命令的一轮),
32
+ * 用于在块与块之间插入间隔(对重复执行的 group 也生效)。
33
+ */
34
+ export function getGroupChunks(groups, specs, options = {}) {
35
+ const { ignorePlatform = false } = options;
36
+ const chunks = [];
37
+ for (const { name, repeat } of specs) {
38
+ const cmds = groups[name];
39
+ if (!cmds)
40
+ continue;
41
+ const supported = ignorePlatform ? cmds : cmds.filter((c) => isSupportedOnCurrentPlatform(c));
42
+ const n = Math.max(1, repeat);
43
+ for (let i = 0; i < n; i++) {
44
+ chunks.push([...supported]);
45
+ }
46
+ }
47
+ return chunks;
48
+ }
49
+ function sleep(ms) {
50
+ return new Promise((r) => setTimeout(r, ms));
51
+ }
52
+ /**
53
+ * 按块顺序执行:每块内顺序执行命令,块与块之间可选间隔(对重复执行的 group 也生效)。
54
+ */
55
+ export async function runGroupChunks(chunks, options = {}) {
56
+ const { stopOnError = false, silent = false, intervalMs = 0, waitForBackground = false } = options;
57
+ const allResults = [];
58
+ let failed = false;
59
+ const aggregateBackground = [];
60
+ let shuttingDown = false;
61
+ const cleanupHandlers = [];
62
+ /** 跨 group 块共享,使 captureToVar 与 {{var}} 可在不同组之间传递 */
63
+ const commandContext = {};
64
+ const onSignal = (signal) => {
65
+ if (shuttingDown)
66
+ return;
67
+ shuttingDown = true;
68
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
69
+ (async () => {
70
+ if (!silent) {
71
+ console.log(`\n收到 ${signal},正在清理后台进程...`);
72
+ }
73
+ try {
74
+ await finalizeBackgroundProcesses(aggregateBackground, false, true);
75
+ }
76
+ finally {
77
+ process.exit(130);
78
+ }
79
+ })();
80
+ };
81
+ cleanupHandlers.push(withSignalHandler('SIGINT', () => onSignal('SIGINT')));
82
+ cleanupHandlers.push(withSignalHandler('SIGTERM', () => onSignal('SIGTERM')));
83
+ if (process.platform === 'win32') {
84
+ cleanupHandlers.push(withSignalHandler('SIGBREAK', () => onSignal('SIGBREAK')));
85
+ }
86
+ // 计算全局命令总数,用于跨组显示统一的 cur/all 进度。
87
+ const totalCommands = chunks.reduce((sum, c) => sum + c.length, 0);
88
+ let executedCount = 0;
89
+ try {
90
+ for (let i = 0; i < chunks.length; i++) {
91
+ if (i > 0 && intervalMs > 0 && !silent) {
92
+ console.log(`\n⏱ 等待 ${intervalMs}ms...`);
93
+ await sleep(intervalMs);
94
+ }
95
+ const chunk = chunks[i];
96
+ if (chunk.length === 0)
97
+ continue;
98
+ const results = await executeAll(chunk, {
99
+ stopOnError,
100
+ silent,
101
+ offset: executedCount,
102
+ total: totalCommands,
103
+ aggregateBackgroundChildren: aggregateBackground,
104
+ commandContext,
105
+ });
106
+ allResults.push(...results);
107
+ executedCount += chunk.length;
108
+ const chunkFailed = results.some((r) => !r.success);
109
+ if (chunkFailed)
110
+ failed = true;
111
+ if (chunkFailed && stopOnError)
112
+ break;
113
+ }
114
+ if (aggregateBackground.length > 0) {
115
+ await finalizeBackgroundProcesses(aggregateBackground, waitForBackground, silent);
116
+ }
117
+ }
118
+ finally {
119
+ cleanupHandlers.forEach((dispose) => dispose());
120
+ }
121
+ return { results: allResults, failed };
122
+ }
123
+ //# sourceMappingURL=runGroups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runGroups.js","sourceRoot":"","sources":["../../src/runGroups.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { CommandDef, CommandResult } from '../types.js';
2
+ import type { CommandRunner, RunnerExecuteOptions } from './types.js';
3
+ export declare class BuiltinFunctionCommandRunner implements CommandRunner {
4
+ canRun(cmd: CommandDef): boolean;
5
+ execute(cmd: CommandDef, options: RunnerExecuteOptions): Promise<CommandResult>;
6
+ }
7
+ //# sourceMappingURL=builtinFunctionRunner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtinFunctionRunner.d.ts","sourceRoot":"","sources":["../../../src/runners/builtinFunctionRunner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEtE,qBAAa,4BAA6B,YAAW,aAAa;IAChE,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IAI1B,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC;CAgDtF"}
@@ -0,0 +1,56 @@
1
+ import { CommandKind } from '../types.js';
2
+ export class BuiltinFunctionCommandRunner {
3
+ canRun(cmd) {
4
+ return cmd.kind === CommandKind.BuiltinFunction;
5
+ }
6
+ async execute(cmd, options) {
7
+ if (typeof cmd.func !== 'function') {
8
+ return {
9
+ kind: CommandKind.BuiltinFunction,
10
+ description: cmd.description ?? 'builtin-function',
11
+ success: false,
12
+ exitCode: null,
13
+ stdout: '',
14
+ stderr: 'builtin-function 命令缺少 func 函数',
15
+ durationMs: Date.now() - options.start,
16
+ };
17
+ }
18
+ if (cmd.background) {
19
+ return {
20
+ kind: CommandKind.BuiltinFunction,
21
+ description: cmd.description ?? cmd.func.name ?? 'builtin-function',
22
+ success: false,
23
+ exitCode: null,
24
+ stdout: '',
25
+ stderr: 'builtin-function 暂不支持 background=true',
26
+ durationMs: Date.now() - options.start,
27
+ };
28
+ }
29
+ try {
30
+ const status = await cmd.func(options.commandContext);
31
+ const success = status !== false;
32
+ return {
33
+ kind: CommandKind.BuiltinFunction,
34
+ description: cmd.description ?? cmd.func.name ?? 'builtin-function',
35
+ success,
36
+ exitCode: success ? 0 : 1,
37
+ stdout: '',
38
+ stderr: success ? '' : 'builtin-function 返回 false',
39
+ durationMs: Date.now() - options.start,
40
+ };
41
+ }
42
+ catch (error) {
43
+ const message = error instanceof Error ? error.message : String(error);
44
+ return {
45
+ kind: CommandKind.BuiltinFunction,
46
+ description: cmd.description ?? cmd.func.name ?? 'builtin-function',
47
+ success: false,
48
+ exitCode: null,
49
+ stdout: '',
50
+ stderr: message,
51
+ durationMs: Date.now() - options.start,
52
+ };
53
+ }
54
+ }
55
+ }
56
+ //# sourceMappingURL=builtinFunctionRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtinFunctionRunner.js","sourceRoot":"","sources":["../../../src/runners/builtinFunctionRunner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI1C,MAAM,OAAO,4BAA4B;IACvC,MAAM,CAAC,GAAe;QACpB,OAAO,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,eAAe,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAe,EAAE,OAA6B;QAC1D,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACnC,OAAO;gBACL,IAAI,EAAE,WAAW,CAAC,eAAe;gBACjC,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,kBAAkB;gBAClD,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,+BAA+B;gBACvC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK;aACvC,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACnB,OAAO;gBACL,IAAI,EAAE,WAAW,CAAC,eAAe;gBACjC,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,kBAAkB;gBACnE,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,uCAAuC;gBAC/C,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK;aACvC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,MAAM,KAAK,KAAK,CAAC;YACjC,OAAO;gBACL,IAAI,EAAE,WAAW,CAAC,eAAe;gBACjC,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,kBAAkB;gBACnE,OAAO;gBACP,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzB,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,2BAA2B;gBAClD,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK;aACvC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO;gBACL,IAAI,EAAE,WAAW,CAAC,eAAe;gBACjC,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,kBAAkB;gBACnE,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,OAAO;gBACf,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK;aACvC,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { CommandDef, CommandResult } from '../types.js';
2
+ import type { CommandRunner, RunnerExecuteOptions } from './types.js';
3
+ export declare class EmbedCommandRunner implements CommandRunner {
4
+ canRun(cmd: CommandDef): boolean;
5
+ execute(cmd: CommandDef, options: RunnerExecuteOptions): Promise<CommandResult>;
6
+ }
7
+ //# sourceMappingURL=embedRunner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedRunner.d.ts","sourceRoot":"","sources":["../../../src/runners/embedRunner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA6GtE,qBAAa,kBAAmB,YAAW,aAAa;IACtD,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IAI1B,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC;CAetF"}