@omni-oss/task-bench 0.0.0-beta.1 → 0.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/dist/bench/index.d.ts +1 -6
- package/dist/bench/index.d.ts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-D3XyMXAu.mjs → src-DOsUAz2Z.mjs} +172 -182
- package/dist/suite/index.d.ts +0 -1
- package/dist/suite/index.d.ts.map +1 -1
- package/dist/suite/report.d.ts.map +1 -1
- package/dist/task-bench-cli.mjs +30 -31
- package/package.json +1 -1
- package/src/bench/index.ts +3 -26
- package/src/cli/index.ts +0 -14
- package/src/suite/index.ts +0 -3
- package/src/suite/report.ts +0 -2
package/dist/bench/index.d.ts
CHANGED
|
@@ -3,8 +3,7 @@ import { Stats } from './stats';
|
|
|
3
3
|
export interface RunSample {
|
|
4
4
|
durationMs: number;
|
|
5
5
|
exitCode: number;
|
|
6
|
-
|
|
7
|
-
stderr: string;
|
|
6
|
+
stdoutBytes: number;
|
|
8
7
|
/** Number of tasks that actually executed (0 == a full cache hit). */
|
|
9
8
|
executed: number;
|
|
10
9
|
ok: boolean;
|
|
@@ -51,10 +50,6 @@ export type BenchEvent = {
|
|
|
51
50
|
kind: "tool-error";
|
|
52
51
|
tool: Tool;
|
|
53
52
|
error: string;
|
|
54
|
-
} | {
|
|
55
|
-
kind: "tool-unsuccessful";
|
|
56
|
-
tool: Tool;
|
|
57
|
-
sample: RunSample;
|
|
58
53
|
};
|
|
59
54
|
export interface RunBenchmarkOptions {
|
|
60
55
|
tools?: Tool[] | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bench/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAuB,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAG3D,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,SAAS;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bench/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAuB,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAG3D,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,SAAS;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,UAAU,GAChB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAClC;IACI,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,CAAC;CACrB,GACD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAChC,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACvD;AAoED;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAC9B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAClC,OAAO,CAAC,eAAe,CAAC,CAgJ1B"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as e, C as t, D as n, E as r, M as i, N as a, O as o, S as s, T as c, _ as l, a as u, b as d, c as f, d as p, f as m, g as h, h as g, i as _, j as v, k as y, l as b, m as x, n as S, o as C, p as w, r as T, s as E, t as D, u as O, v as k, w as A, x as j, y as M } from "./src-
|
|
1
|
+
import { A as e, C as t, D as n, E as r, M as i, N as a, O as o, S as s, T as c, _ as l, a as u, b as d, c as f, d as p, f as m, g as h, h as g, i as _, j as v, k as y, l as b, m as x, n as S, o as C, p as w, r as T, s as E, t as D, u as O, v as k, w as A, x as j, y as M } from "./src-DOsUAz2Z.mjs";
|
|
2
2
|
export { T as BUILTIN_PRESETS, c as DEPENDENCY_STRATEGIES, r as DependencyConfigSchema, n as DependencyStrategySchema, o as HarnessConfigSchema, _ as RunOptionsSchema, u as ScenarioSchema, C as SuiteSchema, y as TOOLS, e as TaskConfigSchema, v as ToolSchema, i as VersionsConfigSchema, k as assertSupportedVersion, s as buildGraph, h as computeStats, E as deepMerge, l as formatMs, w as formatReport, D as formatSuiteMarkdown, m as generateWorkspace, M as getAdapter, d as getAdapters, f as getPreset, x as installWorkspace, b as listPresets, O as parseSuite, t as projectName, a as resolveConfig, p as resolveScenario, j as resolveToolVersions, g as runBenchmark, S as runSuite, A as taskNames };
|
|
@@ -7,46 +7,46 @@ import { execa as f } from "execa";
|
|
|
7
7
|
import { z as p } from "zod";
|
|
8
8
|
import { satisfies as m } from "semver";
|
|
9
9
|
import { stringify as h } from "yaml";
|
|
10
|
-
//#region
|
|
11
|
-
var g =
|
|
10
|
+
//#region src/config.ts
|
|
11
|
+
var g = [
|
|
12
12
|
"isolated",
|
|
13
13
|
"chain",
|
|
14
14
|
"fan-out",
|
|
15
15
|
"layered",
|
|
16
16
|
"random"
|
|
17
|
-
],
|
|
17
|
+
], _ = p.enum(g), v = [
|
|
18
18
|
"omni",
|
|
19
19
|
"turbo",
|
|
20
20
|
"nx",
|
|
21
21
|
"moon"
|
|
22
|
-
],
|
|
23
|
-
strategy:
|
|
22
|
+
], y = p.enum(v), b = p.object({
|
|
23
|
+
strategy: _.default("layered").describe("Shape of the inter-project dependency graph."),
|
|
24
24
|
layers: p.number().int().positive().default(5).describe("Number of layers for the `layered` strategy."),
|
|
25
25
|
fanout: p.number().int().nonnegative().default(3).describe("Maximum number of upstream dependencies per project (cap for `layered`/`random`)."),
|
|
26
26
|
edgeProbability: p.number().min(0).max(1).default(.35).describe("Edge inclusion probability for the `random` strategy.")
|
|
27
|
-
}).prefault({}),
|
|
27
|
+
}).prefault({}), x = p.object({
|
|
28
28
|
logLines: p.number().int().nonnegative().default(25).describe("How many log lines each task prints to stdout."),
|
|
29
29
|
workIterations: p.number().int().nonnegative().default(15e4).describe("Iterations of cheap CPU work per task. Keep small so caching dominates."),
|
|
30
30
|
outputFiles: p.number().int().positive().default(1).describe("Number of output files each task writes into dist/."),
|
|
31
31
|
chainWithinProject: p.boolean().default(!0).describe("Whether task `tN` depends on `t(N-1)` within a project."),
|
|
32
32
|
fanUpstream: p.boolean().default(!0).describe("Whether task `tN` depends on `tN` of upstream projects (^tN).")
|
|
33
|
-
}).prefault({}),
|
|
33
|
+
}).prefault({}), S = p.object({
|
|
34
34
|
turbo: p.string().default("2.10.3"),
|
|
35
35
|
nx: p.string().default("23.0.1"),
|
|
36
36
|
moon: p.string().default("2.3.5"),
|
|
37
37
|
bun: p.string().default("1.3.14")
|
|
38
|
-
}).prefault({}),
|
|
38
|
+
}).prefault({}), C = p.object({
|
|
39
39
|
seed: p.number().int().nonnegative().default(1).describe("Seed for deterministic graph generation."),
|
|
40
40
|
projectPrefix: p.string().regex(/^[a-z][a-z0-9-]*$/).default("bench-p").describe("Prefix used for generated package names."),
|
|
41
41
|
projects: p.number().int().positive().default(50).describe("Number of projects to generate."),
|
|
42
42
|
tasksPerProject: p.number().int().positive().default(3).describe("Number of tasks (t0..tN-1) per project."),
|
|
43
|
-
dependency:
|
|
44
|
-
task:
|
|
45
|
-
tools: p.array(
|
|
46
|
-
versions:
|
|
43
|
+
dependency: b,
|
|
44
|
+
task: x,
|
|
45
|
+
tools: p.array(y).min(1).default([...v]).describe("Which runners to configure and benchmark."),
|
|
46
|
+
versions: S
|
|
47
47
|
});
|
|
48
|
-
function
|
|
49
|
-
return
|
|
48
|
+
function w(e) {
|
|
49
|
+
return C.parse(e ?? {});
|
|
50
50
|
}
|
|
51
51
|
//#endregion
|
|
52
52
|
//#region src/graph.ts
|
|
@@ -61,7 +61,7 @@ function ee(e) {
|
|
|
61
61
|
function te(e) {
|
|
62
62
|
return Math.max(4, String(e - 1).length);
|
|
63
63
|
}
|
|
64
|
-
function
|
|
64
|
+
function T(e, t) {
|
|
65
65
|
let n = te(e.projects);
|
|
66
66
|
return `${e.projectPrefix}${String(t).padStart(n, "0")}`;
|
|
67
67
|
}
|
|
@@ -95,10 +95,10 @@ function re(e, t, n) {
|
|
|
95
95
|
default: return [];
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
-
function
|
|
98
|
+
function E(e) {
|
|
99
99
|
let t = ee(e.seed), n = [];
|
|
100
100
|
for (let r = 0; r < e.projects; r++) {
|
|
101
|
-
let i =
|
|
101
|
+
let i = T(e, r);
|
|
102
102
|
n.push({
|
|
103
103
|
index: r,
|
|
104
104
|
name: i,
|
|
@@ -108,48 +108,48 @@ function k(e) {
|
|
|
108
108
|
}
|
|
109
109
|
return n;
|
|
110
110
|
}
|
|
111
|
-
function
|
|
111
|
+
function D(e) {
|
|
112
112
|
return Array.from({ length: e.tasksPerProject }, (e, t) => `t${t}`);
|
|
113
113
|
}
|
|
114
114
|
//#endregion
|
|
115
115
|
//#region src/tools/types.ts
|
|
116
|
-
function
|
|
116
|
+
function O(t, n) {
|
|
117
117
|
let r = o(t, "node_modules", ".bin", n);
|
|
118
118
|
return e(r) ? r : n;
|
|
119
119
|
}
|
|
120
|
-
async function
|
|
120
|
+
async function k(e) {
|
|
121
121
|
await Promise.all(e.projectDirs.map((t) => l(o(e.rootDir, t, "dist"), {
|
|
122
122
|
recursive: !0,
|
|
123
123
|
force: !0
|
|
124
124
|
})));
|
|
125
125
|
}
|
|
126
|
-
function
|
|
126
|
+
function A(e, t) {
|
|
127
127
|
let n = [];
|
|
128
128
|
return e.task.chainWithinProject && t > 0 && n.push(`t${t - 1}`), e.task.fanUpstream && n.push(`^t${t}`), n;
|
|
129
129
|
}
|
|
130
|
-
function
|
|
130
|
+
function j(e, t) {
|
|
131
131
|
return e.dependencies.map((e) => t[e]?.name ?? "");
|
|
132
132
|
}
|
|
133
133
|
//#endregion
|
|
134
134
|
//#region src/tools/moon.ts
|
|
135
|
-
var
|
|
136
|
-
function
|
|
135
|
+
var ie = "https://moonrepo.dev/schemas/workspace.json", ae = "https://moonrepo.dev/schemas/toolchain.json", oe = "https://moonrepo.dev/schemas/project.json";
|
|
136
|
+
function se(e, t) {
|
|
137
137
|
let n = [];
|
|
138
138
|
return e.task.chainWithinProject && t > 0 && n.push(`~:t${t - 1}`), e.task.fanUpstream && n.push(`^:t${t}`), n;
|
|
139
139
|
}
|
|
140
|
-
function
|
|
140
|
+
function ce() {
|
|
141
141
|
return h({
|
|
142
|
-
$schema:
|
|
142
|
+
$schema: ie,
|
|
143
143
|
projects: ["packages/*"]
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
|
-
function
|
|
147
|
-
return h({ $schema:
|
|
146
|
+
function le() {
|
|
147
|
+
return h({ $schema: ae });
|
|
148
148
|
}
|
|
149
|
-
function
|
|
149
|
+
function ue(e, t, n) {
|
|
150
150
|
let r = {};
|
|
151
|
-
return
|
|
152
|
-
let i =
|
|
151
|
+
return D(e).forEach((t, n) => {
|
|
152
|
+
let i = se(e, n);
|
|
153
153
|
r[t] = {
|
|
154
154
|
command: `node ./task.mjs ${t}`,
|
|
155
155
|
...i.length ? { deps: i } : {},
|
|
@@ -161,26 +161,26 @@ function de(e, t, n) {
|
|
|
161
161
|
outputs: [`dist/${t}.*`]
|
|
162
162
|
};
|
|
163
163
|
}), h({
|
|
164
|
-
$schema:
|
|
164
|
+
$schema: oe,
|
|
165
165
|
id: t.name,
|
|
166
166
|
layer: "library",
|
|
167
167
|
language: "javascript",
|
|
168
|
-
...t.dependencies.length ? { dependsOn:
|
|
168
|
+
...t.dependencies.length ? { dependsOn: j(t, n) } : {},
|
|
169
169
|
tasks: r
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
|
-
var
|
|
172
|
+
var de = {
|
|
173
173
|
tool: "moon",
|
|
174
174
|
hasDaemon: !1,
|
|
175
175
|
supportedVersions: ["^2.0.0"],
|
|
176
176
|
pinnedVersion: (e) => e.versions.moon,
|
|
177
177
|
devDependencies: (e) => ({ "@moonrepo/cli": e.versions.moon }),
|
|
178
178
|
setup: async (e) => {
|
|
179
|
-
await e.write(".moon/workspace.yml",
|
|
180
|
-
for (let t of e.projects) await e.write(`${t.dir}/moon.yml`,
|
|
179
|
+
await e.write(".moon/workspace.yml", ce()), await e.write(".moon/toolchain.yml", le());
|
|
180
|
+
for (let t of e.projects) await e.write(`${t.dir}/moon.yml`, ue(e.config, t, e.projects));
|
|
181
181
|
},
|
|
182
182
|
run: (e, t) => ({
|
|
183
|
-
file:
|
|
183
|
+
file: O(t.rootDir, "moon"),
|
|
184
184
|
args: [
|
|
185
185
|
"run",
|
|
186
186
|
`:${e}`,
|
|
@@ -190,7 +190,7 @@ var fe = {
|
|
|
190
190
|
}),
|
|
191
191
|
env: () => ({}),
|
|
192
192
|
clearCaches: async (e) => {
|
|
193
|
-
await
|
|
193
|
+
await k(e), await l(o(e.rootDir, ".moon", "cache"), {
|
|
194
194
|
recursive: !0,
|
|
195
195
|
force: !0
|
|
196
196
|
});
|
|
@@ -199,11 +199,11 @@ var fe = {
|
|
|
199
199
|
};
|
|
200
200
|
//#endregion
|
|
201
201
|
//#region src/tools/nx.ts
|
|
202
|
-
function
|
|
202
|
+
function fe(e) {
|
|
203
203
|
let t = {};
|
|
204
|
-
return
|
|
204
|
+
return D(e).forEach((n, r) => {
|
|
205
205
|
t[n] = {
|
|
206
|
-
dependsOn:
|
|
206
|
+
dependsOn: A(e, r),
|
|
207
207
|
cache: !0,
|
|
208
208
|
outputs: [`{projectRoot}/dist/${n}.*`],
|
|
209
209
|
inputs: [
|
|
@@ -217,9 +217,9 @@ function pe(e) {
|
|
|
217
217
|
targetDefaults: t
|
|
218
218
|
}, null, 2)}\n`;
|
|
219
219
|
}
|
|
220
|
-
function
|
|
220
|
+
function pe(e, t) {
|
|
221
221
|
let n = {};
|
|
222
|
-
for (let r of
|
|
222
|
+
for (let r of D(e)) n[r] = {
|
|
223
223
|
executor: "nx:run-commands",
|
|
224
224
|
options: {
|
|
225
225
|
command: `node ./task.mjs ${r}`,
|
|
@@ -232,18 +232,18 @@ function me(e, t) {
|
|
|
232
232
|
targets: n
|
|
233
233
|
}, null, 2)}\n`;
|
|
234
234
|
}
|
|
235
|
-
var
|
|
235
|
+
var me = {
|
|
236
236
|
tool: "nx",
|
|
237
237
|
hasDaemon: !0,
|
|
238
238
|
supportedVersions: [">=21.0.0 <24.0.0"],
|
|
239
239
|
pinnedVersion: (e) => e.versions.nx,
|
|
240
240
|
devDependencies: (e) => ({ nx: e.versions.nx }),
|
|
241
241
|
setup: async (e) => {
|
|
242
|
-
await e.write("nx.json",
|
|
243
|
-
for (let t of e.projects) await e.write(`${t.dir}/project.json`,
|
|
242
|
+
await e.write("nx.json", fe(e.config));
|
|
243
|
+
for (let t of e.projects) await e.write(`${t.dir}/project.json`, pe(e.config, t));
|
|
244
244
|
},
|
|
245
245
|
run: (e, t) => ({
|
|
246
|
-
file:
|
|
246
|
+
file: O(t.rootDir, "nx"),
|
|
247
247
|
args: [
|
|
248
248
|
"run-many",
|
|
249
249
|
"-t",
|
|
@@ -256,7 +256,7 @@ var he = {
|
|
|
256
256
|
NX_TUI: "false"
|
|
257
257
|
}),
|
|
258
258
|
clearCaches: async (e) => {
|
|
259
|
-
await
|
|
259
|
+
await k(e), await f(O(e.rootDir, "nx"), ["reset"], {
|
|
260
260
|
cwd: e.rootDir,
|
|
261
261
|
reject: !1,
|
|
262
262
|
stdio: "ignore",
|
|
@@ -267,32 +267,32 @@ var he = {
|
|
|
267
267
|
});
|
|
268
268
|
},
|
|
269
269
|
stopDaemon: async (e) => {
|
|
270
|
-
await f(
|
|
270
|
+
await f(O(e.rootDir, "nx"), ["reset"], {
|
|
271
271
|
cwd: e.rootDir,
|
|
272
272
|
reject: !1,
|
|
273
273
|
stdio: "ignore",
|
|
274
274
|
env: { NX_DAEMON: "false" }
|
|
275
275
|
});
|
|
276
276
|
}
|
|
277
|
-
},
|
|
278
|
-
function
|
|
279
|
-
return `${
|
|
277
|
+
}, he = "# yaml-language-server: $schema=https://raw.githubusercontent.com/omni-oss/json-schemas/refs/heads/main/project.json", ge = "# yaml-language-server: $schema=https://raw.githubusercontent.com/omni-oss/json-schemas/refs/heads/main/workspace.json";
|
|
278
|
+
function _e() {
|
|
279
|
+
return `${ge}\n${h({
|
|
280
280
|
ui: "stream",
|
|
281
281
|
projects: ["packages/*"]
|
|
282
282
|
})}`;
|
|
283
283
|
}
|
|
284
|
-
function
|
|
284
|
+
function ve(e, t, n) {
|
|
285
285
|
let r = {};
|
|
286
|
-
return
|
|
287
|
-
let i =
|
|
286
|
+
return D(e).forEach((t, n) => {
|
|
287
|
+
let i = A(e, n);
|
|
288
288
|
r[t] = {
|
|
289
289
|
exec: `node ./task.mjs ${t}`,
|
|
290
290
|
...i.length ? { dependencies: i } : {},
|
|
291
291
|
cache: { output: { files: [`dist/${t}.*`] } }
|
|
292
292
|
};
|
|
293
|
-
}), `${
|
|
293
|
+
}), `${he}\n${h({
|
|
294
294
|
name: t.name,
|
|
295
|
-
...t.dependencies.length ? { dependencies:
|
|
295
|
+
...t.dependencies.length ? { dependencies: j(t, n) } : {},
|
|
296
296
|
cache: { key: { files: [
|
|
297
297
|
"package.json",
|
|
298
298
|
"task.mjs",
|
|
@@ -301,7 +301,7 @@ function ye(e, t, n) {
|
|
|
301
301
|
tasks: r
|
|
302
302
|
})}`;
|
|
303
303
|
}
|
|
304
|
-
var
|
|
304
|
+
var ye = {
|
|
305
305
|
tool: "omni",
|
|
306
306
|
hasDaemon: !1,
|
|
307
307
|
supportedVersions: [">=0.16.0"],
|
|
@@ -315,8 +315,8 @@ var be = {
|
|
|
315
315
|
},
|
|
316
316
|
devDependencies: () => ({}),
|
|
317
317
|
setup: async (e) => {
|
|
318
|
-
await e.write("workspace.omni.yaml",
|
|
319
|
-
for (let t of e.projects) await e.write(`${t.dir}/project.omni.yaml`,
|
|
318
|
+
await e.write("workspace.omni.yaml", _e());
|
|
319
|
+
for (let t of e.projects) await e.write(`${t.dir}/project.omni.yaml`, ve(e.config, t, e.projects));
|
|
320
320
|
},
|
|
321
321
|
run: (e, t) => ({
|
|
322
322
|
file: "omni",
|
|
@@ -331,7 +331,7 @@ var be = {
|
|
|
331
331
|
}),
|
|
332
332
|
env: () => ({}),
|
|
333
333
|
clearCaches: async (e) => {
|
|
334
|
-
await
|
|
334
|
+
await k(e), await l(o(e.rootDir, ".omni", "cache"), {
|
|
335
335
|
recursive: !0,
|
|
336
336
|
force: !0
|
|
337
337
|
});
|
|
@@ -340,11 +340,11 @@ var be = {
|
|
|
340
340
|
};
|
|
341
341
|
//#endregion
|
|
342
342
|
//#region src/tools/turbo.ts
|
|
343
|
-
function
|
|
343
|
+
function be(e) {
|
|
344
344
|
let t = {};
|
|
345
|
-
return
|
|
345
|
+
return D(e).forEach((n, r) => {
|
|
346
346
|
t[n] = {
|
|
347
|
-
dependsOn:
|
|
347
|
+
dependsOn: A(e, r),
|
|
348
348
|
outputs: [`dist/${n}.*`],
|
|
349
349
|
inputs: [
|
|
350
350
|
"package.json",
|
|
@@ -360,8 +360,8 @@ function xe(e) {
|
|
|
360
360
|
}
|
|
361
361
|
//#endregion
|
|
362
362
|
//#region src/tools/index.ts
|
|
363
|
-
var
|
|
364
|
-
omni:
|
|
363
|
+
var xe = {
|
|
364
|
+
omni: ye,
|
|
365
365
|
turbo: {
|
|
366
366
|
tool: "turbo",
|
|
367
367
|
hasDaemon: !0,
|
|
@@ -369,10 +369,10 @@ var Se = {
|
|
|
369
369
|
pinnedVersion: (e) => e.versions.turbo,
|
|
370
370
|
devDependencies: (e) => ({ turbo: e.versions.turbo }),
|
|
371
371
|
setup: async (e) => {
|
|
372
|
-
await e.write("turbo.json",
|
|
372
|
+
await e.write("turbo.json", be(e.config));
|
|
373
373
|
},
|
|
374
374
|
run: (e, t) => ({
|
|
375
|
-
file:
|
|
375
|
+
file: O(t.rootDir, "turbo"),
|
|
376
376
|
args: [
|
|
377
377
|
"run",
|
|
378
378
|
e,
|
|
@@ -383,7 +383,7 @@ var Se = {
|
|
|
383
383
|
}),
|
|
384
384
|
env: () => ({}),
|
|
385
385
|
clearCaches: async (e) => {
|
|
386
|
-
await
|
|
386
|
+
await k(e), await l(o(e.rootDir, ".turbo"), {
|
|
387
387
|
recursive: !0,
|
|
388
388
|
force: !0
|
|
389
389
|
}), await l(o(e.rootDir, "node_modules", ".cache", "turbo"), {
|
|
@@ -392,39 +392,39 @@ var Se = {
|
|
|
392
392
|
});
|
|
393
393
|
},
|
|
394
394
|
stopDaemon: async (e) => {
|
|
395
|
-
await f(
|
|
395
|
+
await f(O(e.rootDir, "turbo"), ["daemon", "stop"], {
|
|
396
396
|
cwd: e.rootDir,
|
|
397
397
|
reject: !1,
|
|
398
398
|
stdio: "ignore"
|
|
399
399
|
});
|
|
400
400
|
}
|
|
401
401
|
},
|
|
402
|
-
nx:
|
|
403
|
-
moon:
|
|
402
|
+
nx: me,
|
|
403
|
+
moon: de
|
|
404
404
|
};
|
|
405
|
-
function
|
|
406
|
-
return
|
|
405
|
+
function M(e) {
|
|
406
|
+
return xe[e];
|
|
407
407
|
}
|
|
408
|
-
function
|
|
409
|
-
return e.map(
|
|
408
|
+
function N(e) {
|
|
409
|
+
return e.map(M);
|
|
410
410
|
}
|
|
411
|
-
function
|
|
411
|
+
function P(e, t) {
|
|
412
412
|
if (!e.supportedVersions.some((e) => m(t, e, {
|
|
413
413
|
includePrerelease: !0,
|
|
414
414
|
loose: !0
|
|
415
415
|
}))) throw Error(`${e.tool} version "${t}" is not supported by task-bench (supported: ${e.supportedVersions.join(" || ")}). Adjust versions.${e.tool} in your config or upgrade/downgrade the tool.`);
|
|
416
416
|
}
|
|
417
|
-
async function
|
|
417
|
+
async function F(e, t, n = e.tools) {
|
|
418
418
|
let r = /* @__PURE__ */ new Map();
|
|
419
419
|
for (let i of n) {
|
|
420
|
-
let n =
|
|
421
|
-
a === null && n.detectVersion && (a = await n.detectVersion(t)), a !== null &&
|
|
420
|
+
let n = M(i), a = n.pinnedVersion(e);
|
|
421
|
+
a === null && n.detectVersion && (a = await n.detectVersion(t)), a !== null && P(n, a), r.set(i, a);
|
|
422
422
|
}
|
|
423
423
|
return r;
|
|
424
424
|
}
|
|
425
425
|
//#endregion
|
|
426
426
|
//#region src/bench/stats.ts
|
|
427
|
-
function
|
|
427
|
+
function I(e) {
|
|
428
428
|
if (e.length === 0) return {
|
|
429
429
|
samples: e,
|
|
430
430
|
min: 0,
|
|
@@ -443,17 +443,17 @@ function R(e) {
|
|
|
443
443
|
stddev: Math.sqrt(a)
|
|
444
444
|
};
|
|
445
445
|
}
|
|
446
|
-
function
|
|
446
|
+
function L(e) {
|
|
447
447
|
return e >= 1e3 ? `${(e / 1e3).toFixed(2)}s` : `${e.toFixed(0)}ms`;
|
|
448
448
|
}
|
|
449
449
|
//#endregion
|
|
450
450
|
//#region src/bench/index.ts
|
|
451
|
-
function
|
|
451
|
+
function Se(e) {
|
|
452
452
|
if (e.length === 0) return 0;
|
|
453
453
|
let t = [...e].sort((e, t) => e - t), n = Math.floor(t.length / 2);
|
|
454
454
|
return t.length % 2 == 0 ? ((t[n - 1] ?? 0) + (t[n] ?? 0)) / 2 : t[n] ?? 0;
|
|
455
455
|
}
|
|
456
|
-
function
|
|
456
|
+
function Ce(e) {
|
|
457
457
|
try {
|
|
458
458
|
let n = t(e, "utf8");
|
|
459
459
|
if (n.length === 0) return 0;
|
|
@@ -464,7 +464,7 @@ function we(e) {
|
|
|
464
464
|
return 0;
|
|
465
465
|
}
|
|
466
466
|
}
|
|
467
|
-
async function
|
|
467
|
+
async function R(e, t, r, i, a) {
|
|
468
468
|
n(i, "");
|
|
469
469
|
let o = d.now(), s = await f(e, t, {
|
|
470
470
|
cwd: r,
|
|
@@ -477,31 +477,30 @@ async function B(e, t, r, i, a) {
|
|
|
477
477
|
TASK_BENCH_EXEC_LOG: i,
|
|
478
478
|
...a
|
|
479
479
|
}
|
|
480
|
-
}), c = d.now() - o, l = typeof s.stdout == "string" ? s.stdout : ""
|
|
480
|
+
}), c = d.now() - o, l = typeof s.stdout == "string" ? s.stdout : "";
|
|
481
481
|
return {
|
|
482
482
|
durationMs: c,
|
|
483
483
|
exitCode: s.exitCode ?? -1,
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
executed: we(i),
|
|
484
|
+
stdoutBytes: Buffer.byteLength(l),
|
|
485
|
+
executed: Ce(i),
|
|
487
486
|
ok: s.exitCode === 0
|
|
488
487
|
};
|
|
489
488
|
}
|
|
490
|
-
function
|
|
489
|
+
function z(e) {
|
|
491
490
|
return {
|
|
492
491
|
runs: e.length,
|
|
493
492
|
failures: e.filter((e) => !e.ok).length,
|
|
494
|
-
stats:
|
|
495
|
-
executedMedian:
|
|
493
|
+
stats: I(e.map((e) => e.durationMs)),
|
|
494
|
+
executedMedian: Se(e.map((e) => e.executed))
|
|
496
495
|
};
|
|
497
496
|
}
|
|
498
|
-
async function
|
|
499
|
-
let n = JSON.parse(await c(o(e, "bench.config.json"), "utf8")), a =
|
|
497
|
+
async function B(e, t = {}) {
|
|
498
|
+
let n = JSON.parse(await c(o(e, "bench.config.json"), "utf8")), a = C.parse(n), s = E(a), l = D(a), u = t.tools ?? a.tools, d = t.task ?? l[l.length - 1] ?? "t0", f = t.coldRuns ?? 3, p = t.warmRuns ?? 5, m = t.concurrency ?? Math.max(1, r().length), h = t.daemon ?? !0, g = t.onEvent ?? (() => {}), _ = o(i(), `task-bench-exec-${process.pid}-${Date.now()}.log`), v = {
|
|
500
499
|
rootDir: e,
|
|
501
500
|
projectDirs: s.map((e) => e.dir),
|
|
502
501
|
concurrency: m,
|
|
503
502
|
daemon: h
|
|
504
|
-
}, y = await
|
|
503
|
+
}, y = await F(a, e, u), b = {};
|
|
505
504
|
for (let [e, t] of y) b[e] = t;
|
|
506
505
|
let x = [];
|
|
507
506
|
for (let t of u) {
|
|
@@ -509,13 +508,13 @@ async function H(e, t = {}) {
|
|
|
509
508
|
kind: "tool-start",
|
|
510
509
|
tool: t
|
|
511
510
|
});
|
|
512
|
-
let n =
|
|
511
|
+
let n = M(t), r = n.run(d, v), i = n.env(v);
|
|
513
512
|
try {
|
|
514
513
|
!h && n.hasDaemon && await n.stopDaemon(v);
|
|
515
514
|
let a = [];
|
|
516
515
|
for (let o = 1; o <= f; o++) {
|
|
517
516
|
await n.clearCaches(v), h && n.hasDaemon && await n.stopDaemon(v);
|
|
518
|
-
let s = await
|
|
517
|
+
let s = await R(r.file, r.args, e, _, i);
|
|
519
518
|
a.push(s), g({
|
|
520
519
|
kind: "scenario",
|
|
521
520
|
tool: t,
|
|
@@ -523,16 +522,12 @@ async function H(e, t = {}) {
|
|
|
523
522
|
run: o,
|
|
524
523
|
total: f,
|
|
525
524
|
sample: s
|
|
526
|
-
}), s.exitCode !== 0 && g({
|
|
527
|
-
kind: "tool-unsuccessful",
|
|
528
|
-
tool: t,
|
|
529
|
-
sample: s
|
|
530
525
|
});
|
|
531
526
|
}
|
|
532
|
-
await
|
|
527
|
+
await R(r.file, r.args, e, _, i);
|
|
533
528
|
let o = [];
|
|
534
529
|
for (let n = 1; n <= p; n++) {
|
|
535
|
-
let a = await
|
|
530
|
+
let a = await R(r.file, r.args, e, _, i);
|
|
536
531
|
o.push(a), g({
|
|
537
532
|
kind: "scenario",
|
|
538
533
|
tool: t,
|
|
@@ -540,10 +535,6 @@ async function H(e, t = {}) {
|
|
|
540
535
|
run: n,
|
|
541
536
|
total: p,
|
|
542
537
|
sample: a
|
|
543
|
-
}), a.exitCode !== 0 && g({
|
|
544
|
-
kind: "tool-unsuccessful",
|
|
545
|
-
tool: t,
|
|
546
|
-
sample: a
|
|
547
538
|
});
|
|
548
539
|
}
|
|
549
540
|
let s = Math.max(0, ...a.map((e) => e.executed), ...o.map((e) => e.executed));
|
|
@@ -551,8 +542,8 @@ async function H(e, t = {}) {
|
|
|
551
542
|
tool: t,
|
|
552
543
|
task: d,
|
|
553
544
|
taskGraphSize: s,
|
|
554
|
-
cold:
|
|
555
|
-
warm:
|
|
545
|
+
cold: z(a),
|
|
546
|
+
warm: z(o)
|
|
556
547
|
});
|
|
557
548
|
} catch (e) {
|
|
558
549
|
let n = e instanceof Error ? e.message : String(e);
|
|
@@ -564,8 +555,8 @@ async function H(e, t = {}) {
|
|
|
564
555
|
tool: t,
|
|
565
556
|
task: d,
|
|
566
557
|
taskGraphSize: 0,
|
|
567
|
-
cold:
|
|
568
|
-
warm:
|
|
558
|
+
cold: z([]),
|
|
559
|
+
warm: z([]),
|
|
569
560
|
error: n
|
|
570
561
|
});
|
|
571
562
|
} finally {
|
|
@@ -586,7 +577,7 @@ async function H(e, t = {}) {
|
|
|
586
577
|
}
|
|
587
578
|
//#endregion
|
|
588
579
|
//#region src/bench/install.ts
|
|
589
|
-
async function
|
|
580
|
+
async function V(e, t = {}) {
|
|
590
581
|
await f("bun", ["install"], {
|
|
591
582
|
cwd: e,
|
|
592
583
|
stdio: t.quiet ? "ignore" : "inherit"
|
|
@@ -594,24 +585,24 @@ async function U(e, t = {}) {
|
|
|
594
585
|
}
|
|
595
586
|
//#endregion
|
|
596
587
|
//#region src/bench/report.ts
|
|
597
|
-
function
|
|
588
|
+
function we(e, t) {
|
|
598
589
|
return e.length >= t ? e : e + " ".repeat(t - e.length);
|
|
599
590
|
}
|
|
600
|
-
function
|
|
591
|
+
function H(e, t) {
|
|
601
592
|
if (e.samples.length === 0) return "—";
|
|
602
|
-
let n = `${
|
|
593
|
+
let n = `${L(e.median)} ±${L(e.stddev)}`;
|
|
603
594
|
return t > 0 ? `${n} ⚠${t}` : n;
|
|
604
595
|
}
|
|
605
|
-
function
|
|
596
|
+
function U(e) {
|
|
606
597
|
return e.taskGraphSize <= 0 || e.warm.stats.samples.length === 0 ? null : (e.taskGraphSize - e.warm.executedMedian) / e.taskGraphSize * 100;
|
|
607
598
|
}
|
|
608
|
-
function
|
|
609
|
-
let t =
|
|
599
|
+
function Te(e) {
|
|
600
|
+
let t = U(e);
|
|
610
601
|
return t === null ? "—" : `${t.toFixed(0)}%`;
|
|
611
602
|
}
|
|
612
|
-
function
|
|
603
|
+
function W(e) {
|
|
613
604
|
let t = [], n = Math.max(0, ...e.tools.map((e) => e.taskGraphSize));
|
|
614
|
-
t.push(""), t.push(`task-bench: ${e.projects} projects × ${e.tasksPerProject} tasks (${n} task-graph nodes), running "${e.task}" at concurrency ${e.concurrency} (daemons ${e.daemon ? "on" : "off"})`), t.push(
|
|
605
|
+
t.push(""), t.push(`task-bench: ${e.projects} projects × ${e.tasksPerProject} tasks (${n} task-graph nodes), running "${e.task}" at concurrency ${e.concurrency} (daemons ${e.daemon ? "on" : "off"})`), t.push(Ee(e)), t.push("");
|
|
615
606
|
let r = [
|
|
616
607
|
"tool",
|
|
617
608
|
"cold (median)",
|
|
@@ -622,42 +613,42 @@ function Ee(e) {
|
|
|
622
613
|
let t = e.error ? `error: ${(e.error.split("\n")[0] ?? "").slice(0, 40)}` : "";
|
|
623
614
|
return [
|
|
624
615
|
e.tool,
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
616
|
+
H(e.cold.stats, e.cold.failures),
|
|
617
|
+
H(e.warm.stats, e.warm.failures),
|
|
618
|
+
Te(e),
|
|
628
619
|
t
|
|
629
620
|
];
|
|
630
|
-
}), a = r.map((e, t) => Math.max(e.length, ...i.map((e) => (e[t] ?? "").length))), o = (e) => `| ${e.map((e, t) =>
|
|
621
|
+
}), a = r.map((e, t) => Math.max(e.length, ...i.map((e) => (e[t] ?? "").length))), o = (e) => `| ${e.map((e, t) => we(e, a[t] ?? 0)).join(" | ")} |`;
|
|
631
622
|
t.push(o(r)), t.push(`| ${a.map((e) => "-".repeat(e)).join(" | ")} |`);
|
|
632
623
|
for (let e of i) t.push(o(e));
|
|
633
624
|
t.push("");
|
|
634
625
|
let s = e.tools.filter((e) => {
|
|
635
|
-
let t =
|
|
626
|
+
let t = U(e);
|
|
636
627
|
return t !== null && t < 99.5;
|
|
637
628
|
});
|
|
638
|
-
for (let e of s) t.push(`⚠ ${e.tool}: warm runs were not fully cached (${
|
|
629
|
+
for (let e of s) t.push(`⚠ ${e.tool}: warm runs were not fully cached (${Te(e)} hit, ${e.warm.executedMedian}/${e.taskGraphSize} tasks re-ran) — treat its warm number with caution.`);
|
|
639
630
|
s.length && t.push("");
|
|
640
631
|
let c = e.tools.filter((e) => {
|
|
641
|
-
let t =
|
|
632
|
+
let t = U(e);
|
|
642
633
|
return !e.error && t !== null && t >= 99.5;
|
|
643
634
|
}).sort((e, t) => e.warm.stats.median - t.warm.stats.median), l = c[0], u = c[c.length - 1];
|
|
644
635
|
if (c.length > 1 && l && u) {
|
|
645
636
|
let e = u.warm.stats.median / l.warm.stats.median;
|
|
646
|
-
t.push(`Warm-cache overhead: ${l.tool} is fastest (${
|
|
637
|
+
t.push(`Warm-cache overhead: ${l.tool} is fastest (${L(l.warm.stats.median)}), ${e.toFixed(2)}× faster than ${u.tool} (${L(u.warm.stats.median)}).\n`);
|
|
647
638
|
}
|
|
648
639
|
let d = e.tools.filter((e) => !e.error && e.cold.stats.samples.length > 0).sort((e, t) => e.cold.stats.median - t.cold.stats.median), f = d[0], p = d[d.length - 1];
|
|
649
640
|
if (d.length > 1 && f && p) {
|
|
650
641
|
let e = p.cold.stats.median / f.cold.stats.median;
|
|
651
|
-
t.push(`Cold-run overhead: ${f.tool} is fastest (${
|
|
642
|
+
t.push(`Cold-run overhead: ${f.tool} is fastest (${L(f.cold.stats.median)}), ${e.toFixed(2)}× faster than ${p.tool} (${L(p.cold.stats.median)}).`);
|
|
652
643
|
}
|
|
653
644
|
return (c.length > 1 || d.length > 1) && t.push(""), t.join("\n");
|
|
654
645
|
}
|
|
655
|
-
function
|
|
646
|
+
function Ee(e) {
|
|
656
647
|
return `versions: ${e.tools.map((t) => `\`${t.tool} ${e.versions[t.tool] ?? "?"}\``).join(", ")}`;
|
|
657
648
|
}
|
|
658
649
|
//#endregion
|
|
659
650
|
//#region src/generate/templates.ts
|
|
660
|
-
function
|
|
651
|
+
function De(e) {
|
|
661
652
|
return [
|
|
662
653
|
`// Auto-generated source for ${e.name}.`,
|
|
663
654
|
"// Edit the harness config, not this file.",
|
|
@@ -667,7 +658,7 @@ function Oe(e) {
|
|
|
667
658
|
""
|
|
668
659
|
].join("\n");
|
|
669
660
|
}
|
|
670
|
-
function
|
|
661
|
+
function Oe(e, t) {
|
|
671
662
|
let { logLines: n, workIterations: r, outputFiles: i } = e.task;
|
|
672
663
|
return `#!/usr/bin/env node
|
|
673
664
|
import { createHash } from "node:crypto";
|
|
@@ -724,11 +715,11 @@ console.log(\`[\${PROJECT}] \${task}: complete (\${OUTPUT_FILES} output file(s))
|
|
|
724
715
|
}
|
|
725
716
|
//#endregion
|
|
726
717
|
//#region src/generate/index.ts
|
|
727
|
-
async function
|
|
718
|
+
async function G(e, t, n, r) {
|
|
728
719
|
let i = o(e, t);
|
|
729
720
|
await s(a(i), { recursive: !0 }), await u(i, n), r.push(t);
|
|
730
721
|
}
|
|
731
|
-
function
|
|
722
|
+
function ke(e, t) {
|
|
732
723
|
let n = {};
|
|
733
724
|
for (let r of t) Object.assign(n, r.devDependencies(e));
|
|
734
725
|
return `${JSON.stringify({
|
|
@@ -739,9 +730,9 @@ function Ae(e, t) {
|
|
|
739
730
|
...Object.keys(n).length ? { devDependencies: n } : {}
|
|
740
731
|
}, null, 2)}\n`;
|
|
741
732
|
}
|
|
742
|
-
function
|
|
733
|
+
function Ae(e, t, n) {
|
|
743
734
|
let r = {};
|
|
744
|
-
for (let t of
|
|
735
|
+
for (let t of D(e)) r[t] = `node ./task.mjs ${t}`;
|
|
745
736
|
let i = {};
|
|
746
737
|
for (let e of t.dependencies) {
|
|
747
738
|
let t = n[e];
|
|
@@ -755,7 +746,7 @@ function je(e, t, n) {
|
|
|
755
746
|
...Object.keys(i).length ? { dependencies: i } : {}
|
|
756
747
|
}, null, 2)}\n`;
|
|
757
748
|
}
|
|
758
|
-
function
|
|
749
|
+
function je() {
|
|
759
750
|
return [
|
|
760
751
|
"node_modules",
|
|
761
752
|
"dist",
|
|
@@ -767,7 +758,7 @@ function Me() {
|
|
|
767
758
|
""
|
|
768
759
|
].join("\n");
|
|
769
760
|
}
|
|
770
|
-
function
|
|
761
|
+
function Me(e) {
|
|
771
762
|
return [
|
|
772
763
|
"# task-bench harness",
|
|
773
764
|
"",
|
|
@@ -783,7 +774,7 @@ function Ne(e) {
|
|
|
783
774
|
""
|
|
784
775
|
].join("\n");
|
|
785
776
|
}
|
|
786
|
-
async function
|
|
777
|
+
async function Ne(e) {
|
|
787
778
|
let t = {
|
|
788
779
|
cwd: e,
|
|
789
780
|
reject: !1,
|
|
@@ -799,19 +790,19 @@ async function Pe(e) {
|
|
|
799
790
|
"generated benchmark workspace"
|
|
800
791
|
], t);
|
|
801
792
|
}
|
|
802
|
-
async function
|
|
803
|
-
let n =
|
|
793
|
+
async function K(e, t) {
|
|
794
|
+
let n = w(t), r = E(n), i = [], a = N(n.tools);
|
|
804
795
|
await l(e, {
|
|
805
796
|
recursive: !0,
|
|
806
797
|
force: !0
|
|
807
798
|
}), await s(e, { recursive: !0 });
|
|
808
|
-
let o = await
|
|
809
|
-
await
|
|
799
|
+
let o = await F(n, e);
|
|
800
|
+
await G(e, "package.json", ke(n, a), i), await G(e, ".gitignore", je(), i), await G(e, "README.md", Me(n), i), await G(e, "bench.config.json", `${JSON.stringify(n, null, 2)}\n`, i);
|
|
810
801
|
for (let t of r) {
|
|
811
802
|
let a = t.dir;
|
|
812
|
-
await
|
|
803
|
+
await G(e, `${a}/package.json`, Ae(n, t, r), i), await G(e, `${a}/src/index.js`, De(t), i), await G(e, `${a}/task.mjs`, Oe(n, t), i);
|
|
813
804
|
}
|
|
814
|
-
let c = (t, n) =>
|
|
805
|
+
let c = (t, n) => G(e, t, n, i);
|
|
815
806
|
for (let t of a) await t.setup({
|
|
816
807
|
rootDir: e,
|
|
817
808
|
config: n,
|
|
@@ -819,7 +810,7 @@ async function Fe(e, t) {
|
|
|
819
810
|
version: o.get(t.tool) ?? null,
|
|
820
811
|
write: c
|
|
821
812
|
});
|
|
822
|
-
return await
|
|
813
|
+
return await Ne(e), {
|
|
823
814
|
rootDir: e,
|
|
824
815
|
config: n,
|
|
825
816
|
projects: r,
|
|
@@ -828,39 +819,39 @@ async function Fe(e, t) {
|
|
|
828
819
|
}
|
|
829
820
|
//#endregion
|
|
830
821
|
//#region src/suite/preset.ts
|
|
831
|
-
var
|
|
832
|
-
tools: p.array(
|
|
822
|
+
var q = p.object({
|
|
823
|
+
tools: p.array(y).optional(),
|
|
833
824
|
task: p.string().optional(),
|
|
834
825
|
coldRuns: p.number().int().nonnegative().optional(),
|
|
835
826
|
warmRuns: p.number().int().nonnegative().optional(),
|
|
836
827
|
concurrency: p.number().int().positive().optional(),
|
|
837
828
|
daemon: p.boolean().optional()
|
|
838
|
-
}).default({}),
|
|
829
|
+
}).default({}), J = p.record(p.string(), p.unknown()).default({}), Pe = p.object({
|
|
839
830
|
name: p.string().regex(/^[a-zA-Z0-9._-]+$/, "scenario name must be filesystem-safe (letters, digits, . _ -)"),
|
|
840
831
|
description: p.string().optional(),
|
|
841
|
-
config:
|
|
842
|
-
run:
|
|
832
|
+
config: J,
|
|
833
|
+
run: q
|
|
843
834
|
}), Y = p.object({
|
|
844
835
|
name: p.string().default("task-bench suite"),
|
|
845
836
|
description: p.string().optional(),
|
|
846
837
|
defaults: p.object({
|
|
847
|
-
config:
|
|
848
|
-
run:
|
|
838
|
+
config: J,
|
|
839
|
+
run: q
|
|
849
840
|
}).prefault({}),
|
|
850
|
-
scenarios: p.array(
|
|
841
|
+
scenarios: p.array(Pe).min(1)
|
|
851
842
|
});
|
|
852
|
-
function
|
|
843
|
+
function Fe(e) {
|
|
853
844
|
return typeof e == "object" && !!e && !Array.isArray(e);
|
|
854
845
|
}
|
|
855
846
|
function X(e, t) {
|
|
856
847
|
let n = { ...e };
|
|
857
848
|
for (let [e, r] of Object.entries(t)) {
|
|
858
849
|
let t = n[e];
|
|
859
|
-
n[e] =
|
|
850
|
+
n[e] = Fe(t) && Fe(r) ? X(t, r) : r;
|
|
860
851
|
}
|
|
861
852
|
return n;
|
|
862
853
|
}
|
|
863
|
-
function
|
|
854
|
+
function Ie(e, t) {
|
|
864
855
|
let n = X(e.defaults.config, t.config), r = {
|
|
865
856
|
...e.defaults.run,
|
|
866
857
|
...t.run
|
|
@@ -868,7 +859,7 @@ function ze(e, t) {
|
|
|
868
859
|
return {
|
|
869
860
|
name: t.name,
|
|
870
861
|
description: t.description,
|
|
871
|
-
config:
|
|
862
|
+
config: w(n),
|
|
872
863
|
run: r
|
|
873
864
|
};
|
|
874
865
|
}
|
|
@@ -1040,25 +1031,25 @@ var Z = [
|
|
|
1040
1031
|
]
|
|
1041
1032
|
}
|
|
1042
1033
|
};
|
|
1043
|
-
function
|
|
1034
|
+
function Le() {
|
|
1044
1035
|
return Object.keys(Q);
|
|
1045
1036
|
}
|
|
1046
|
-
function
|
|
1037
|
+
function Re(e) {
|
|
1047
1038
|
let t = Q[e];
|
|
1048
|
-
if (!t) throw Error(`unknown preset "${e}" (available: ${
|
|
1039
|
+
if (!t) throw Error(`unknown preset "${e}" (available: ${Le().join(", ")})`);
|
|
1049
1040
|
return Y.parse(t);
|
|
1050
1041
|
}
|
|
1051
|
-
function
|
|
1042
|
+
function ze(e) {
|
|
1052
1043
|
return Y.parse(e);
|
|
1053
1044
|
}
|
|
1054
1045
|
//#endregion
|
|
1055
1046
|
//#region src/suite/index.ts
|
|
1056
|
-
async function
|
|
1047
|
+
async function Be(e, t) {
|
|
1057
1048
|
let n = t.onEvent ?? (() => {}), r = [], i = e.scenarios.length;
|
|
1058
1049
|
for (let a = 0; a < i; a++) {
|
|
1059
1050
|
let s = e.scenarios[a];
|
|
1060
1051
|
if (!s) continue;
|
|
1061
|
-
let c =
|
|
1052
|
+
let c = Ie(e, s), { config: u, run: d } = c, f = t.overrides?.tools ?? d.tools ?? u.tools;
|
|
1062
1053
|
u.tools = f;
|
|
1063
1054
|
let p = o(t.workdir, c.name);
|
|
1064
1055
|
n({
|
|
@@ -1066,8 +1057,8 @@ async function Ue(e, t) {
|
|
|
1066
1057
|
name: c.name,
|
|
1067
1058
|
index: a,
|
|
1068
1059
|
total: i
|
|
1069
|
-
}), await
|
|
1070
|
-
let m = await
|
|
1060
|
+
}), await K(p, u), t.install !== !1 && await V(p, { quiet: !0 });
|
|
1061
|
+
let m = await B(p, {
|
|
1071
1062
|
tools: f,
|
|
1072
1063
|
task: t.overrides?.task ?? d.task,
|
|
1073
1064
|
coldRuns: t.overrides?.coldRuns ?? d.coldRuns,
|
|
@@ -1100,29 +1091,28 @@ async function Ue(e, t) {
|
|
|
1100
1091
|
name: e.name,
|
|
1101
1092
|
description: e.description,
|
|
1102
1093
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1103
|
-
scenarios: r
|
|
1104
|
-
taskBenchVersion: v
|
|
1094
|
+
scenarios: r
|
|
1105
1095
|
};
|
|
1106
1096
|
}
|
|
1107
1097
|
//#endregion
|
|
1108
1098
|
//#region src/suite/report.ts
|
|
1109
|
-
function
|
|
1099
|
+
function Ve(e) {
|
|
1110
1100
|
let t = /* @__PURE__ */ new Set();
|
|
1111
1101
|
for (let n of e.scenarios) for (let e of n.result.tools) t.add(e.tool);
|
|
1112
|
-
return
|
|
1102
|
+
return v.filter((e) => t.has(e));
|
|
1113
1103
|
}
|
|
1114
|
-
function
|
|
1104
|
+
function He(e, t) {
|
|
1115
1105
|
return `Tool versions:\n\n${t.map((t) => `\`${t} ${e.scenarios.map((e) => e.result.versions[t]).find((e) => e != null) ?? "?"}\``).join("\n\n")}`;
|
|
1116
1106
|
}
|
|
1117
|
-
function
|
|
1107
|
+
function Ue(e, t) {
|
|
1118
1108
|
let n = e.result.tools.find((e) => e.tool === t);
|
|
1119
1109
|
if (!n || n.error) return n?.error ? "err" : "—";
|
|
1120
|
-
let r = n.taskGraphSize > 0 ? (n.taskGraphSize - n.warm.executedMedian) / n.taskGraphSize : 1, i =
|
|
1110
|
+
let r = n.taskGraphSize > 0 ? (n.taskGraphSize - n.warm.executedMedian) / n.taskGraphSize : 1, i = L(n.warm.stats.median);
|
|
1121
1111
|
return r < .995 ? `${i}⚠` : i;
|
|
1122
1112
|
}
|
|
1123
|
-
function
|
|
1113
|
+
function We(e, t) {
|
|
1124
1114
|
let n = e.result.tools.find((e) => e.tool === t);
|
|
1125
|
-
return !n || n.error ? n?.error ? "err" : "—" :
|
|
1115
|
+
return !n || n.error ? n?.error ? "err" : "—" : L(n.cold.stats.median);
|
|
1126
1116
|
}
|
|
1127
1117
|
function $(e, t) {
|
|
1128
1118
|
let n = e.map((e, n) => Math.max(e.length, ...t.map((e) => (e[n] ?? "").length))), r = (e, t) => e.padEnd(t), i = (e) => `| ${e.map((e, t) => r(e, n[t] ?? 0)).join(" | ")} |`;
|
|
@@ -1132,9 +1122,9 @@ function $(e, t) {
|
|
|
1132
1122
|
...t.map(i)
|
|
1133
1123
|
];
|
|
1134
1124
|
}
|
|
1135
|
-
function
|
|
1136
|
-
let t =
|
|
1137
|
-
n.push(`# ${e.name}`), n.push(""),
|
|
1125
|
+
function Ge(e) {
|
|
1126
|
+
let t = Ve(e), n = [];
|
|
1127
|
+
n.push(`# ${e.name}`), n.push(""), e.description && (n.push(e.description), n.push("")), n.push(`Generated ${e.generatedAt} · ${e.scenarios.length} scenario(s).`), n.push(""), n.push(He(e, t)), n.push(""), n.push("`warm` = median wall time with a verified 100% cache hit (discovery + cache-restore overhead). `⚠` marks a scenario whose warm runs were not fully cached. Absolute times are hardware-dependent — read the ratios."), n.push(""), n.push("## Summary — warm median"), n.push(""), n.push(...$([
|
|
1138
1128
|
"scenario",
|
|
1139
1129
|
"nodes",
|
|
1140
1130
|
"conc",
|
|
@@ -1145,7 +1135,7 @@ function Je(e) {
|
|
|
1145
1135
|
String(e.result.tools[0]?.taskGraphSize ?? 0),
|
|
1146
1136
|
String(e.result.concurrency),
|
|
1147
1137
|
e.result.daemon ? "on" : "off",
|
|
1148
|
-
...t.map((t) =>
|
|
1138
|
+
...t.map((t) => Ue(e, t))
|
|
1149
1139
|
]))), n.push(""), n.push("## Summary — cold median"), n.push(""), n.push(...$([
|
|
1150
1140
|
"scenario",
|
|
1151
1141
|
"nodes",
|
|
@@ -1155,13 +1145,13 @@ function Je(e) {
|
|
|
1155
1145
|
e.name,
|
|
1156
1146
|
String(e.result.tools[0]?.taskGraphSize ?? 0),
|
|
1157
1147
|
String(e.result.concurrency),
|
|
1158
|
-
...t.map((t) =>
|
|
1148
|
+
...t.map((t) => We(e, t))
|
|
1159
1149
|
]))), n.push(""), n.push("## Details"), n.push("");
|
|
1160
1150
|
for (let t of e.scenarios) {
|
|
1161
1151
|
let e = t.description ? `${t.name} — ${t.description}` : t.name;
|
|
1162
|
-
n.push(`### ${e}`), n.push(`Config: ${t.config.projects} projects × ${t.config.tasksPerProject} tasks, strategy \`${t.config.dependency.strategy}\`.`), n.push(
|
|
1152
|
+
n.push(`### ${e}`), n.push(`Config: ${t.config.projects} projects × ${t.config.tasksPerProject} tasks, strategy \`${t.config.dependency.strategy}\`.`), n.push(W(t.result).trimEnd()), n.push("");
|
|
1163
1153
|
}
|
|
1164
1154
|
return n.join("\n");
|
|
1165
1155
|
}
|
|
1166
1156
|
//#endregion
|
|
1167
|
-
export {
|
|
1157
|
+
export { x as A, T as C, _ as D, b as E, S as M, w as N, C as O, E as S, g as T, L as _, Pe as a, N as b, Re as c, Ie as d, K as f, I as g, B as h, q as i, y as j, v as k, Le as l, V as m, Be as n, Y as o, W as p, Q as r, X as s, Ge as t, ze as u, P as v, D as w, F as x, M as y };
|
package/dist/suite/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/suite/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/suite/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAgB,MAAM,UAAU,CAAC;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,KAAK,UAAU,EAAmB,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAE9E,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,aAAa,CAAC;IACtB,GAAG,EAAE,UAAU,CAAC;IAChB,MAAM,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,mBAAmB,EAAE,CAAC;CACpC;AAED,MAAM,MAAM,UAAU,GAChB;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC5B,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACvD;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAC1B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,eAAe,GACzB,OAAO,CAAC,WAAW,CAAC,CA8DtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/suite/report.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,SAAS,CAAC;AAqDhE;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/suite/report.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,SAAS,CAAC;AAqDhE;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAwE9D"}
|
package/dist/task-bench-cli.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { readFileSync as
|
|
4
|
-
import { tmpdir as
|
|
5
|
-
import { join as
|
|
6
|
-
import { Command as
|
|
7
|
-
//#region
|
|
8
|
-
var C = new
|
|
9
|
-
C.name(
|
|
2
|
+
import { N as e, T as t, _ as n, c as r, f as i, h as a, k as o, l as s, m as c, n as l, p as u, t as d, u as f } from "./src-DOsUAz2Z.mjs";
|
|
3
|
+
import { readFileSync as p, writeFileSync as m } from "node:fs";
|
|
4
|
+
import { tmpdir as h } from "node:os";
|
|
5
|
+
import { join as g, resolve as _ } from "node:path";
|
|
6
|
+
import { Command as v, Option as y } from "@commander-js/extra-typings";
|
|
7
|
+
//#region package.json
|
|
8
|
+
var b = "@omni-oss/task-bench", x = "Generate configurable test workspaces and benchmark omni/turbo/nx task execution performance", S = "0.0.0", C = new v();
|
|
9
|
+
C.name(b).version(S).description(x);
|
|
10
10
|
var w = (e) => {
|
|
11
11
|
let t = Number.parseInt(e, 10);
|
|
12
12
|
if (Number.isNaN(t)) throw Error(`expected an integer, got "${e}"`);
|
|
@@ -17,11 +17,11 @@ var w = (e) => {
|
|
|
17
17
|
return t;
|
|
18
18
|
}, E = (e) => e.split(",").map((e) => {
|
|
19
19
|
let t = e.trim();
|
|
20
|
-
if (!
|
|
20
|
+
if (!o.includes(t)) throw Error(`unknown tool "${t}" (allowed: ${o.join(", ")})`);
|
|
21
21
|
return t;
|
|
22
22
|
});
|
|
23
23
|
function D(e) {
|
|
24
|
-
let t = e.config ? JSON.parse(
|
|
24
|
+
let t = e.config ? JSON.parse(p(e.config, "utf8")) : {}, n = { ...t };
|
|
25
25
|
e.seed !== void 0 && (n.seed = e.seed), e.projects !== void 0 && (n.projects = e.projects), e.tasks !== void 0 && (n.tasksPerProject = e.tasks), e.tools !== void 0 && (n.tools = e.tools);
|
|
26
26
|
let r = { ...t.dependency ?? {} };
|
|
27
27
|
e.strategy !== void 0 && (r.strategy = e.strategy), e.layers !== void 0 && (r.layers = e.layers), e.fanout !== void 0 && (r.fanout = e.fanout), e.edgeProbability !== void 0 && (r.edgeProbability = e.edgeProbability), Object.keys(r).length && (n.dependency = r);
|
|
@@ -31,27 +31,26 @@ function D(e) {
|
|
|
31
31
|
return e.turboVersion !== void 0 && (a.turbo = e.turboVersion), e.nxVersion !== void 0 && (a.nx = e.nxVersion), e.moonVersion !== void 0 && (a.moon = e.moonVersion), e.bunVersion !== void 0 && (a.bun = e.bunVersion), Object.keys(a).length && (n.versions = a), n;
|
|
32
32
|
}
|
|
33
33
|
function O(e) {
|
|
34
|
-
return e.option("--config <file>", "Base config JSON file to extend.").option("--seed <n>", "Deterministic graph seed.", w).option("--projects <n>", "Number of projects.", w).option("--tasks <n>", "Tasks per project.", w).addOption(new
|
|
34
|
+
return e.option("--config <file>", "Base config JSON file to extend.").option("--seed <n>", "Deterministic graph seed.", w).option("--projects <n>", "Number of projects.", w).option("--tasks <n>", "Tasks per project.", w).addOption(new y("--strategy <name>", "Dependency graph strategy.").choices(t)).option("--layers <n>", "Layers for the `layered` strategy.", w).option("--fanout <n>", "Max upstream deps per project.", w).option("--edge-probability <p>", "Edge probability for `random`.", T).option("--log-lines <n>", "Log lines printed per task.", w).option("--work <n>", "CPU work iterations per task.", w).option("--output-files <n>", "Output files per task.", w).option("--tools <list>", "Comma-separated tools (omni,turbo,nx,moon).", E).option("--turbo-version <semver>", "Turbo version to install.").option("--nx-version <semver>", "Nx version to install.").option("--moon-version <semver>", "moon (@moonrepo/cli) version to install.").option("--bun-version <semver>", "bun version for packageManager.").option("--no-chain", "Disable intra-project task chaining.").option("--no-fan-upstream", "Disable upstream (^) task dependencies.");
|
|
35
35
|
}
|
|
36
36
|
function k() {
|
|
37
37
|
return (e) => {
|
|
38
38
|
if (e.kind === "tool-start") process.stderr.write(`\n▶ ${e.tool}\n`);
|
|
39
39
|
else if (e.kind === "tool-error") process.stderr.write(` ✖ ${e.tool}: ${e.error}\n`);
|
|
40
|
-
else if (e.kind === "tool-unsuccessful") process.stderr.write(` ✖ ${e.tool}: exit ${e.sample.exitCode}\n`), e.sample.stdout && process.stderr.write(` === stdout ===\n${e.sample.stdout}\n`), e.sample.stderr && process.stderr.write(` === stderr ===\n${e.sample.stderr}\n`);
|
|
41
40
|
else {
|
|
42
41
|
let t = e.sample.ok ? "ok" : `exit ${e.sample.exitCode}`;
|
|
43
|
-
process.stderr.write(` ${e.scenario} ${e.run}/${e.total}: ${
|
|
42
|
+
process.stderr.write(` ${e.scenario} ${e.run}/${e.total}: ${n(e.sample.durationMs)} (ran ${e.sample.executed} tasks, ${t})\n`);
|
|
44
43
|
}
|
|
45
44
|
};
|
|
46
45
|
}
|
|
47
46
|
function A(e, t) {
|
|
48
|
-
e && (
|
|
47
|
+
e && (m(e, `${JSON.stringify(t, null, 2)}\n`), process.stderr.write(`\nWrote results to ${e}\n`));
|
|
49
48
|
}
|
|
50
49
|
O(C.command("generate").alias("gen").description("Generate a benchmark workspace at the given root dir.").requiredOption("-o, --out <dir>", "Root dir to generate the workspace into.")).action(async (e) => {
|
|
51
|
-
let t =
|
|
50
|
+
let t = _(e.out), n = await i(t, D(e));
|
|
52
51
|
process.stderr.write(`Generated ${n.projects.length} projects (${n.files.length} files) at ${t}\nTools: ${n.config.tools.join(", ")}\n`);
|
|
53
52
|
}), C.command("run").description("Benchmark an already-generated workspace.").requiredOption("-d, --dir <dir>", "Root dir of a generated workspace.").option("--tools <list>", "Comma-separated tools to benchmark.", E).option("--task <name>", "Task to run (defaults to the last task).").option("--cold-runs <n>", "Cold (uncached) runs per tool.", w, 3).option("--warm-runs <n>", "Warm (cached) runs per tool.", w, 5).option("--concurrency <n>", "Max parallel tasks, applied identically to all tools (default: CPU count).", w).option("--no-daemon", "Disable each tool's persistent daemon (turbo, nx).").option("--json <file>", "Write full results as JSON to this file.").action(async (e) => {
|
|
54
|
-
let t = await
|
|
53
|
+
let t = await a(_(e.dir), {
|
|
55
54
|
tools: e.tools,
|
|
56
55
|
task: e.task,
|
|
57
56
|
concurrency: e.concurrency,
|
|
@@ -60,11 +59,11 @@ O(C.command("generate").alias("gen").description("Generate a benchmark workspace
|
|
|
60
59
|
warmRuns: e.warmRuns,
|
|
61
60
|
onEvent: k()
|
|
62
61
|
});
|
|
63
|
-
process.stdout.write(
|
|
62
|
+
process.stdout.write(u(t)), A(e.json, t);
|
|
64
63
|
}), O(C.command("bench").description("Generate, install, and benchmark in one step.").requiredOption("-o, --out <dir>", "Root dir to generate the workspace into.").option("--no-install", "Skip `bun install` in the generated workspace.").option("--task <name>", "Task to run (defaults to the last task).").option("--cold-runs <n>", "Cold (uncached) runs per tool.", w, 3).option("--warm-runs <n>", "Warm (cached) runs per tool.", w, 5).option("--concurrency <n>", "Max parallel tasks, applied identically to all tools (default: CPU count).", w).option("--no-daemon", "Disable each tool's persistent daemon (turbo, nx).").option("--json <file>", "Write full results as JSON to this file.")).action(async (e) => {
|
|
65
|
-
let t =
|
|
66
|
-
process.stderr.write(`Generated ${n.projects.length} projects at ${t}\n`), e.install !== !1 && (process.stderr.write("Installing dependencies (bun install)...\n"), await
|
|
67
|
-
let r = await
|
|
64
|
+
let t = _(e.out), n = await i(t, D(e));
|
|
65
|
+
process.stderr.write(`Generated ${n.projects.length} projects at ${t}\n`), e.install !== !1 && (process.stderr.write("Installing dependencies (bun install)...\n"), await c(t));
|
|
66
|
+
let r = await a(t, {
|
|
68
67
|
task: e.task,
|
|
69
68
|
coldRuns: e.coldRuns,
|
|
70
69
|
warmRuns: e.warmRuns,
|
|
@@ -72,10 +71,10 @@ O(C.command("generate").alias("gen").description("Generate a benchmark workspace
|
|
|
72
71
|
daemon: e.daemon,
|
|
73
72
|
onEvent: k()
|
|
74
73
|
});
|
|
75
|
-
process.stdout.write(
|
|
76
|
-
}), O(C.command("inspect").description("Resolve a config and print the derived graph summary.")).action((
|
|
77
|
-
let
|
|
78
|
-
process.stdout.write(`${JSON.stringify(
|
|
74
|
+
process.stdout.write(u(r)), A(e.json, r);
|
|
75
|
+
}), O(C.command("inspect").description("Resolve a config and print the derived graph summary.")).action((t) => {
|
|
76
|
+
let n = e(D(t));
|
|
77
|
+
process.stdout.write(`${JSON.stringify(n, null, 2)}\n`);
|
|
79
78
|
});
|
|
80
79
|
function j() {
|
|
81
80
|
let e = k();
|
|
@@ -85,23 +84,23 @@ function j() {
|
|
|
85
84
|
}
|
|
86
85
|
C.command("suite").description("Run a preset (or JSON file) of benchmark scenarios and summarize them.").option("-p, --preset <name>", "Built-in preset name.").option("-f, --file <path>", "Path to a JSON suite preset file.").option("-o, --out <dir>", "Working dir for generated workspaces.").option("--json <file>", "Write aggregated results as JSON to this file.").option("--md <file>", "Write a human-readable Markdown report to this file.").option("--tools <list>", "Override tools for every scenario.", E).option("--cold-runs <n>", "Override cold runs for every scenario.", w).option("--warm-runs <n>", "Override warm runs for every scenario.", w).option("--concurrency <n>", "Override concurrency for every scenario.", w).option("--no-install", "Skip `bun install` in generated workspaces.").option("--keep", "Keep generated workspaces instead of removing them.").option("--list", "List the built-in presets and exit.").action(async (e) => {
|
|
87
86
|
if (e.list) {
|
|
88
|
-
process.stdout.write(`Available presets:\n${
|
|
87
|
+
process.stdout.write(`Available presets:\n${s().map((e) => ` - ${e}`).join("\n")}\n`);
|
|
89
88
|
return;
|
|
90
89
|
}
|
|
91
|
-
let t = e.file ?
|
|
90
|
+
let t = e.file ? f(JSON.parse(p(e.file, "utf8"))) : r(e.preset ?? "quick"), n = _(e.out ?? g(h(), "task-bench-suite"));
|
|
92
91
|
process.stderr.write(`Running suite "${t.name}" (${t.scenarios.length} scenarios) in ${n}\n`);
|
|
93
|
-
let
|
|
92
|
+
let i = {
|
|
94
93
|
...e.tools ? { tools: e.tools } : {},
|
|
95
94
|
...e.coldRuns === void 0 ? {} : { coldRuns: e.coldRuns },
|
|
96
95
|
...e.warmRuns === void 0 ? {} : { warmRuns: e.warmRuns },
|
|
97
96
|
...e.concurrency === void 0 ? {} : { concurrency: e.concurrency }
|
|
98
|
-
},
|
|
97
|
+
}, a = await l(t, {
|
|
99
98
|
workdir: n,
|
|
100
99
|
install: e.install,
|
|
101
100
|
keep: e.keep,
|
|
102
|
-
overrides:
|
|
101
|
+
overrides: i,
|
|
103
102
|
onEvent: j()
|
|
104
|
-
}),
|
|
105
|
-
process.stdout.write(`\n${
|
|
103
|
+
}), o = d(a);
|
|
104
|
+
process.stdout.write(`\n${o}\n`), e.md && (m(e.md, `${o}\n`), process.stderr.write(`\nWrote Markdown report to ${e.md}\n`)), e.json && (m(e.json, `${JSON.stringify(a, null, 2)}\n`), process.stderr.write(`Wrote JSON results to ${e.json}\n`));
|
|
106
105
|
}), C.parseAsync();
|
|
107
106
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omni-oss/task-bench",
|
|
3
3
|
"description": "Generate configurable test workspaces and benchmark omni/turbo/nx task execution performance",
|
|
4
|
-
"version": "0.0.0
|
|
4
|
+
"version": "0.0.0",
|
|
5
5
|
"bin": "./dist/task-bench-cli.mjs",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
package/src/bench/index.ts
CHANGED
|
@@ -12,8 +12,7 @@ import { computeStats, type Stats } from "./stats";
|
|
|
12
12
|
export interface RunSample {
|
|
13
13
|
durationMs: number;
|
|
14
14
|
exitCode: number;
|
|
15
|
-
|
|
16
|
-
stderr: string;
|
|
15
|
+
stdoutBytes: number;
|
|
17
16
|
/** Number of tasks that actually executed (0 == a full cache hit). */
|
|
18
17
|
executed: number;
|
|
19
18
|
ok: boolean;
|
|
@@ -60,12 +59,7 @@ export type BenchEvent =
|
|
|
60
59
|
total: number;
|
|
61
60
|
sample: RunSample;
|
|
62
61
|
}
|
|
63
|
-
| { kind: "tool-error"; tool: Tool; error: string }
|
|
64
|
-
| {
|
|
65
|
-
kind: "tool-unsuccessful";
|
|
66
|
-
tool: Tool;
|
|
67
|
-
sample: RunSample;
|
|
68
|
-
};
|
|
62
|
+
| { kind: "tool-error"; tool: Tool; error: string };
|
|
69
63
|
|
|
70
64
|
export interface RunBenchmarkOptions {
|
|
71
65
|
tools?: Tool[] | undefined;
|
|
@@ -124,15 +118,12 @@ async function timeRun(
|
|
|
124
118
|
...extraEnv,
|
|
125
119
|
},
|
|
126
120
|
});
|
|
127
|
-
|
|
128
121
|
const durationMs = performance.now() - start;
|
|
129
122
|
const stdout = typeof result.stdout === "string" ? result.stdout : "";
|
|
130
|
-
const stderr = typeof result.stderr === "string" ? result.stderr : "";
|
|
131
123
|
return {
|
|
132
124
|
durationMs,
|
|
133
125
|
exitCode: result.exitCode ?? -1,
|
|
134
|
-
stdout,
|
|
135
|
-
stderr,
|
|
126
|
+
stdoutBytes: Buffer.byteLength(stdout),
|
|
136
127
|
executed: countLines(execLog),
|
|
137
128
|
ok: result.exitCode === 0,
|
|
138
129
|
};
|
|
@@ -233,13 +224,6 @@ export async function runBenchmark(
|
|
|
233
224
|
total: coldRuns,
|
|
234
225
|
sample,
|
|
235
226
|
});
|
|
236
|
-
if (sample.exitCode !== 0) {
|
|
237
|
-
emit({
|
|
238
|
-
kind: "tool-unsuccessful",
|
|
239
|
-
tool,
|
|
240
|
-
sample,
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
227
|
}
|
|
244
228
|
|
|
245
229
|
// Warm scenario: prime once (unmeasured, also warms the daemon),
|
|
@@ -269,13 +253,6 @@ export async function runBenchmark(
|
|
|
269
253
|
total: warmRuns,
|
|
270
254
|
sample,
|
|
271
255
|
});
|
|
272
|
-
if (sample.exitCode !== 0) {
|
|
273
|
-
emit({
|
|
274
|
-
kind: "tool-unsuccessful",
|
|
275
|
-
tool,
|
|
276
|
-
sample,
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
256
|
}
|
|
280
257
|
|
|
281
258
|
const taskGraphSize = Math.max(
|
package/src/cli/index.ts
CHANGED
|
@@ -170,20 +170,6 @@ function progressHandler(): (event: BenchEvent) => void {
|
|
|
170
170
|
process.stderr.write(`\n▶ ${event.tool}\n`);
|
|
171
171
|
} else if (event.kind === "tool-error") {
|
|
172
172
|
process.stderr.write(` ✖ ${event.tool}: ${event.error}\n`);
|
|
173
|
-
} else if (event.kind === "tool-unsuccessful") {
|
|
174
|
-
process.stderr.write(
|
|
175
|
-
` ✖ ${event.tool}: exit ${event.sample.exitCode}\n`,
|
|
176
|
-
);
|
|
177
|
-
if (event.sample.stdout) {
|
|
178
|
-
process.stderr.write(
|
|
179
|
-
` === stdout ===\n${event.sample.stdout}\n`,
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
if (event.sample.stderr) {
|
|
183
|
-
process.stderr.write(
|
|
184
|
-
` === stderr ===\n${event.sample.stderr}\n`,
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
173
|
} else {
|
|
188
174
|
const status = event.sample.ok
|
|
189
175
|
? "ok"
|
package/src/suite/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { rm } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { version } from "../../package.json";
|
|
4
3
|
import { type BenchEvent, type BenchmarkResult, runBenchmark } from "../bench";
|
|
5
4
|
import { installWorkspace } from "../bench/install";
|
|
6
5
|
import type { HarnessConfig } from "../config";
|
|
@@ -20,7 +19,6 @@ export interface SuiteResult {
|
|
|
20
19
|
description?: string | undefined;
|
|
21
20
|
generatedAt: string;
|
|
22
21
|
scenarios: SuiteScenarioResult[];
|
|
23
|
-
taskBenchVersion: string;
|
|
24
22
|
}
|
|
25
23
|
|
|
26
24
|
export type SuiteEvent =
|
|
@@ -108,6 +106,5 @@ export async function runSuite(
|
|
|
108
106
|
description: suite.description,
|
|
109
107
|
generatedAt: new Date().toISOString(),
|
|
110
108
|
scenarios,
|
|
111
|
-
taskBenchVersion: version,
|
|
112
109
|
};
|
|
113
110
|
}
|
package/src/suite/report.ts
CHANGED
|
@@ -64,8 +64,6 @@ export function formatSuiteMarkdown(suite: SuiteResult): string {
|
|
|
64
64
|
|
|
65
65
|
lines.push(`# ${suite.name}`);
|
|
66
66
|
lines.push("");
|
|
67
|
-
lines.push(`TaskBench v${suite.taskBenchVersion}`);
|
|
68
|
-
lines.push("");
|
|
69
67
|
if (suite.description) {
|
|
70
68
|
lines.push(suite.description);
|
|
71
69
|
lines.push("");
|