modestbench 0.9.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/cli/builder.cjs +259 -0
- package/dist/cli/builder.cjs.map +1 -0
- package/dist/cli/builder.d.cts +37 -0
- package/dist/cli/builder.d.cts.map +1 -0
- package/dist/cli/builder.d.ts +37 -0
- package/dist/cli/builder.d.ts.map +1 -0
- package/dist/cli/builder.js +255 -0
- package/dist/cli/builder.js.map +1 -0
- package/dist/cli/commands/baseline.cjs +4 -33
- package/dist/cli/commands/baseline.cjs.map +1 -1
- package/dist/cli/commands/baseline.d.cts.map +1 -1
- package/dist/cli/commands/baseline.d.ts.map +1 -1
- package/dist/cli/commands/baseline.js +2 -31
- package/dist/cli/commands/baseline.js.map +1 -1
- package/dist/cli/commands/history.cjs +2 -14
- package/dist/cli/commands/history.cjs.map +1 -1
- package/dist/cli/commands/history.d.cts.map +1 -1
- package/dist/cli/commands/history.d.ts.map +1 -1
- package/dist/cli/commands/history.js +1 -13
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/init.cjs +2 -2
- package/dist/cli/commands/init.cjs.map +1 -1
- package/dist/cli/commands/init.js +2 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/run.cjs +3 -3
- package/dist/cli/commands/run.cjs.map +1 -1
- package/dist/cli/commands/run.d.cts +0 -13
- package/dist/cli/commands/run.d.cts.map +1 -1
- package/dist/cli/commands/run.d.ts +0 -13
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +1 -1
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/test.cjs +1 -1
- package/dist/cli/commands/test.cjs.map +1 -1
- package/dist/cli/commands/test.js +1 -1
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/context.cjs +60 -0
- package/dist/cli/context.cjs.map +1 -0
- package/dist/cli/context.d.cts +28 -0
- package/dist/cli/context.d.cts.map +1 -0
- package/dist/cli/context.d.ts +28 -0
- package/dist/cli/context.d.ts.map +1 -0
- package/dist/cli/context.js +56 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/handlers.cjs +74 -0
- package/dist/cli/handlers.cjs.map +1 -0
- package/dist/cli/handlers.d.cts +13 -0
- package/dist/cli/handlers.d.cts.map +1 -0
- package/dist/cli/handlers.d.ts +13 -0
- package/dist/cli/handlers.d.ts.map +1 -0
- package/dist/cli/handlers.js +70 -0
- package/dist/cli/handlers.js.map +1 -0
- package/dist/cli/index.cjs +45 -978
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +6 -31
- package/dist/cli/index.d.cts.map +1 -1
- package/dist/cli/index.d.ts +6 -31
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +43 -974
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/parsers/analyze.cjs +54 -0
- package/dist/cli/parsers/analyze.cjs.map +1 -0
- package/dist/cli/parsers/analyze.d.cts +37 -0
- package/dist/cli/parsers/analyze.d.cts.map +1 -0
- package/dist/cli/parsers/analyze.d.ts +37 -0
- package/dist/cli/parsers/analyze.d.ts.map +1 -0
- package/dist/cli/parsers/analyze.js +51 -0
- package/dist/cli/parsers/analyze.js.map +1 -0
- package/dist/cli/parsers/baseline.cjs +75 -0
- package/dist/cli/parsers/baseline.cjs.map +1 -0
- package/dist/cli/parsers/baseline.d.cts +59 -0
- package/dist/cli/parsers/baseline.d.cts.map +1 -0
- package/dist/cli/parsers/baseline.d.ts +59 -0
- package/dist/cli/parsers/baseline.d.ts.map +1 -0
- package/dist/cli/parsers/baseline.js +72 -0
- package/dist/cli/parsers/baseline.js.map +1 -0
- package/dist/cli/parsers/global.cjs +49 -0
- package/dist/cli/parsers/global.cjs.map +1 -0
- package/dist/cli/parsers/global.d.cts +45 -0
- package/dist/cli/parsers/global.d.cts.map +1 -0
- package/dist/cli/parsers/global.d.ts +45 -0
- package/dist/cli/parsers/global.d.ts.map +1 -0
- package/dist/cli/parsers/global.js +46 -0
- package/dist/cli/parsers/global.js.map +1 -0
- package/dist/cli/parsers/history.cjs +138 -0
- package/dist/cli/parsers/history.cjs.map +1 -0
- package/dist/cli/parsers/history.d.cts +108 -0
- package/dist/cli/parsers/history.d.cts.map +1 -0
- package/dist/cli/parsers/history.d.ts +108 -0
- package/dist/cli/parsers/history.d.ts.map +1 -0
- package/dist/cli/parsers/history.js +135 -0
- package/dist/cli/parsers/history.js.map +1 -0
- package/dist/cli/parsers/index.cjs +35 -0
- package/dist/cli/parsers/index.cjs.map +1 -0
- package/dist/cli/parsers/index.d.cts +15 -0
- package/dist/cli/parsers/index.d.cts.map +1 -0
- package/dist/cli/parsers/index.d.ts +15 -0
- package/dist/cli/parsers/index.d.ts.map +1 -0
- package/dist/cli/parsers/index.js +15 -0
- package/dist/cli/parsers/index.js.map +1 -0
- package/dist/cli/parsers/init.cjs +39 -0
- package/dist/cli/parsers/init.cjs.map +1 -0
- package/dist/cli/parsers/init.d.cts +32 -0
- package/dist/cli/parsers/init.d.cts.map +1 -0
- package/dist/cli/parsers/init.d.ts +32 -0
- package/dist/cli/parsers/init.d.ts.map +1 -0
- package/dist/cli/parsers/init.js +36 -0
- package/dist/cli/parsers/init.js.map +1 -0
- package/dist/cli/parsers/run.cjs +99 -0
- package/dist/cli/parsers/run.cjs.map +1 -0
- package/dist/cli/parsers/run.d.cts +62 -0
- package/dist/cli/parsers/run.d.cts.map +1 -0
- package/dist/cli/parsers/run.d.ts +62 -0
- package/dist/cli/parsers/run.d.ts.map +1 -0
- package/dist/cli/parsers/run.js +96 -0
- package/dist/cli/parsers/run.js.map +1 -0
- package/dist/cli/parsers/test.cjs +42 -0
- package/dist/cli/parsers/test.cjs.map +1 -0
- package/dist/cli/parsers/test.d.cts +31 -0
- package/dist/cli/parsers/test.d.cts.map +1 -0
- package/dist/cli/parsers/test.d.ts +31 -0
- package/dist/cli/parsers/test.d.ts.map +1 -0
- package/dist/cli/parsers/test.js +39 -0
- package/dist/cli/parsers/test.js.map +1 -0
- package/dist/cli/theme.cjs +35 -0
- package/dist/cli/theme.cjs.map +1 -0
- package/dist/cli/theme.d.cts +31 -0
- package/dist/cli/theme.d.cts.map +1 -0
- package/dist/cli/theme.d.ts +31 -0
- package/dist/cli/theme.d.ts.map +1 -0
- package/dist/cli/theme.js +32 -0
- package/dist/cli/theme.js.map +1 -0
- package/dist/config/budget-schema.cjs +1 -1
- package/dist/config/budget-schema.cjs.map +1 -1
- package/dist/config/budget-schema.js +1 -1
- package/dist/config/budget-schema.js.map +1 -1
- package/dist/core/engines/accurate-engine.cjs +1 -1
- package/dist/core/engines/accurate-engine.cjs.map +1 -1
- package/dist/core/engines/accurate-engine.d.cts.map +1 -1
- package/dist/core/engines/accurate-engine.d.ts.map +1 -1
- package/dist/core/engines/accurate-engine.js +1 -1
- package/dist/core/engines/accurate-engine.js.map +1 -1
- package/dist/errors/base.cjs +3 -12
- package/dist/errors/base.cjs.map +1 -1
- package/dist/errors/base.d.cts +0 -7
- package/dist/errors/base.d.cts.map +1 -1
- package/dist/errors/base.d.ts +0 -7
- package/dist/errors/base.d.ts.map +1 -1
- package/dist/errors/base.js +1 -9
- package/dist/errors/base.js.map +1 -1
- package/dist/formatters/history/compare.cjs +6 -6
- package/dist/formatters/history/compare.cjs.map +1 -1
- package/dist/formatters/history/compare.js +6 -6
- package/dist/formatters/history/compare.js.map +1 -1
- package/dist/formatters/history/show.cjs +2 -2
- package/dist/formatters/history/show.cjs.map +1 -1
- package/dist/formatters/history/show.js +2 -2
- package/dist/formatters/history/show.js.map +1 -1
- package/dist/formatters/history/trends.cjs +1 -1
- package/dist/formatters/history/trends.cjs.map +1 -1
- package/dist/formatters/history/trends.js +1 -1
- package/dist/formatters/history/trends.js.map +1 -1
- package/dist/reporters/human.cjs +3 -3
- package/dist/reporters/human.cjs.map +1 -1
- package/dist/reporters/human.d.cts.map +1 -1
- package/dist/reporters/human.d.ts.map +1 -1
- package/dist/reporters/human.js +3 -3
- package/dist/reporters/human.js.map +1 -1
- package/dist/reporters/nyan.cjs +1 -1
- package/dist/reporters/nyan.cjs.map +1 -1
- package/dist/reporters/nyan.js +1 -1
- package/dist/reporters/nyan.js.map +1 -1
- package/dist/services/budget-evaluator.cjs +2 -2
- package/dist/services/budget-evaluator.cjs.map +1 -1
- package/dist/services/budget-evaluator.js +2 -2
- package/dist/services/budget-evaluator.js.map +1 -1
- package/dist/services/config-manager.cjs +2 -2
- package/dist/services/config-manager.cjs.map +1 -1
- package/dist/services/config-manager.js +2 -2
- package/dist/services/config-manager.js.map +1 -1
- package/dist/services/profiler/profile-runner.cjs +11 -0
- package/dist/services/profiler/profile-runner.cjs.map +1 -1
- package/dist/services/profiler/profile-runner.d.cts +2 -0
- package/dist/services/profiler/profile-runner.d.cts.map +1 -1
- package/dist/services/profiler/profile-runner.d.ts +2 -0
- package/dist/services/profiler/profile-runner.d.ts.map +1 -1
- package/dist/services/profiler/profile-runner.js +11 -0
- package/dist/services/profiler/profile-runner.js.map +1 -1
- package/dist/services/reporter-registry.cjs +8 -8
- package/dist/services/reporter-registry.cjs.map +1 -1
- package/dist/services/reporter-registry.js +8 -8
- package/dist/services/reporter-registry.js.map +1 -1
- package/package.json +7 -9
- package/src/cli/builder.ts +387 -0
- package/src/cli/commands/baseline.ts +7 -33
- package/src/cli/commands/history.ts +1 -16
- package/src/cli/commands/init.ts +2 -2
- package/src/cli/commands/run.ts +1 -1
- package/src/cli/commands/test.ts +1 -1
- package/src/cli/context.ts +117 -0
- package/src/cli/handlers.ts +76 -0
- package/src/cli/index.ts +49 -1194
- package/src/cli/parsers/analyze.ts +61 -0
- package/src/cli/parsers/baseline.ts +92 -0
- package/src/cli/parsers/global.ts +51 -0
- package/src/cli/parsers/history.ts +168 -0
- package/src/cli/parsers/index.ts +28 -0
- package/src/cli/parsers/init.ts +45 -0
- package/src/cli/parsers/run.ts +118 -0
- package/src/cli/parsers/test.ts +46 -0
- package/src/cli/theme.ts +33 -0
- package/src/config/budget-schema.ts +1 -1
- package/src/core/engines/accurate-engine.ts +1 -1
- package/src/errors/base.ts +1 -10
- package/src/formatters/history/compare.ts +6 -6
- package/src/formatters/history/show.ts +2 -2
- package/src/formatters/history/trends.ts +1 -1
- package/src/reporters/human.ts +5 -3
- package/src/reporters/nyan.ts +1 -1
- package/src/services/budget-evaluator.ts +2 -2
- package/src/services/config-manager.ts +2 -2
- package/src/services/profiler/profile-runner.ts +15 -0
- package/src/services/reporter-registry.ts +8 -8
package/dist/cli/index.cjs
CHANGED
|
@@ -3,37 +3,29 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* ModestBench CLI Entry Point
|
|
5
5
|
*
|
|
6
|
-
* Command-line interface using
|
|
7
|
-
*
|
|
6
|
+
* Command-line interface using bargs for command parsing and routing. This
|
|
7
|
+
* module provides the main entry points and re-exports key types.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
8
10
|
*/
|
|
9
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
-
};
|
|
12
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.main = exports.cli = void 0;
|
|
12
|
+
exports.main = exports.cli = exports.createCliContext = void 0;
|
|
13
|
+
const bargs_1 = require("@boneskull/bargs");
|
|
14
14
|
const node_fs_1 = require("node:fs");
|
|
15
15
|
const node_url_1 = require("node:url");
|
|
16
|
-
const yargs_1 = __importDefault(require("yargs"));
|
|
17
|
-
const helpers_1 = require("yargs/helpers");
|
|
18
|
-
const bootstrap_js_1 = require("../bootstrap.cjs");
|
|
19
16
|
const constants_js_1 = require("../constants.cjs");
|
|
20
|
-
const index_js_1 = require("../
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const baseline_js_1 = require("./commands/baseline.cjs");
|
|
27
|
-
const history_js_1 = require("./commands/history.cjs");
|
|
28
|
-
const init_js_1 = require("./commands/init.cjs");
|
|
29
|
-
const run_js_1 = require("./commands/run.cjs");
|
|
30
|
-
const test_js_1 = require("./commands/test.cjs");
|
|
17
|
+
const index_js_1 = require("../errors/index.cjs");
|
|
18
|
+
const builder_js_1 = require("./builder.cjs");
|
|
19
|
+
const handlers_js_1 = require("./handlers.cjs");
|
|
20
|
+
// Re-export types and utilities for external use
|
|
21
|
+
var context_js_1 = require("./context.cjs");
|
|
22
|
+
Object.defineProperty(exports, "createCliContext", { enumerable: true, get: function () { return context_js_1.createCliContext; } });
|
|
31
23
|
/**
|
|
32
24
|
* Initialize and run the CLI
|
|
33
25
|
*/
|
|
34
26
|
const cli = (argv) => {
|
|
35
27
|
const abortController = new AbortController();
|
|
36
|
-
setupSignalHandlers(abortController);
|
|
28
|
+
(0, handlers_js_1.setupSignalHandlers)(abortController);
|
|
37
29
|
(0, exports.main)(argv, abortController).catch((error) => {
|
|
38
30
|
console.error('CLI error:', error);
|
|
39
31
|
process.exit(constants_js_1.ExitCodes.UNKNOWN_ERROR);
|
|
@@ -44,876 +36,41 @@ exports.cli = cli;
|
|
|
44
36
|
* Main CLI entry point
|
|
45
37
|
*/
|
|
46
38
|
const main = async (argv, abortController) => {
|
|
39
|
+
const controller = abortController ?? new AbortController();
|
|
47
40
|
try {
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
// Configure global options and commands
|
|
51
|
-
await cli
|
|
52
|
-
.scriptName('modestbench')
|
|
53
|
-
.option('config', {
|
|
54
|
-
alias: 'c',
|
|
55
|
-
description: 'Path to configuration file',
|
|
56
|
-
global: true,
|
|
57
|
-
type: 'string',
|
|
58
|
-
})
|
|
59
|
-
.option('verbose', {
|
|
60
|
-
alias: 'v',
|
|
61
|
-
defaultDescription: String(run_js_1.RUN_COMMAND_DEFAULTS.verbose),
|
|
62
|
-
description: 'Enable verbose output',
|
|
63
|
-
global: true,
|
|
64
|
-
type: 'boolean',
|
|
65
|
-
})
|
|
66
|
-
.option('no-color', {
|
|
67
|
-
defaultDescription: 'false',
|
|
68
|
-
description: 'Disable colored output',
|
|
69
|
-
global: true,
|
|
70
|
-
type: 'boolean',
|
|
71
|
-
})
|
|
72
|
-
.option('progress', {
|
|
73
|
-
defaultDescription: 'true',
|
|
74
|
-
description: 'Show animated progress bar',
|
|
75
|
-
global: true,
|
|
76
|
-
type: 'boolean',
|
|
77
|
-
})
|
|
78
|
-
.option('json', {
|
|
79
|
-
defaultDescription: 'false',
|
|
80
|
-
description: 'Output results in JSON format',
|
|
81
|
-
global: true,
|
|
82
|
-
type: 'boolean',
|
|
83
|
-
})
|
|
84
|
-
.option('cwd', {
|
|
85
|
-
defaultDescription: '.',
|
|
86
|
-
description: 'Working directory',
|
|
87
|
-
global: true,
|
|
88
|
-
normalize: true,
|
|
89
|
-
type: 'string',
|
|
90
|
-
})
|
|
91
|
-
.help()
|
|
92
|
-
.alias('help', 'h')
|
|
93
|
-
.version()
|
|
94
|
-
.alias('version', 'V')
|
|
95
|
-
.strict()
|
|
96
|
-
.demandCommand(1)
|
|
97
|
-
.recommendCommands()
|
|
98
|
-
.completion()
|
|
99
|
-
.wrap(Math.min(120, cli.terminalWidth()))
|
|
100
|
-
.command(['$0 [pattern..]', 'run [pattern..]'], 'Run benchmark files', (yargs) => yargs
|
|
101
|
-
.positional('pattern', {
|
|
102
|
-
array: true,
|
|
103
|
-
defaultDescription: `(auto-discovered from ${constants_js_1.DEFAULT_BENCHMARK_DIR} directory)`,
|
|
104
|
-
describe: 'File paths, directory paths, or glob patterns for benchmark files',
|
|
105
|
-
type: 'string',
|
|
106
|
-
})
|
|
107
|
-
.option('config', {
|
|
108
|
-
alias: 'c',
|
|
109
|
-
description: 'Path to configuration file',
|
|
110
|
-
type: 'string',
|
|
111
|
-
})
|
|
112
|
-
.option('reporter', {
|
|
113
|
-
alias: 'r',
|
|
114
|
-
array: true,
|
|
115
|
-
choices: Object.values(constants_js_1.Reporters).sort(),
|
|
116
|
-
defaultDescription: constants_js_1.DEFAULT_REPORTER,
|
|
117
|
-
description: 'Output reporters to use (human,json,csv)',
|
|
118
|
-
type: 'string',
|
|
119
|
-
})
|
|
120
|
-
.option('output', {
|
|
121
|
-
alias: 'o',
|
|
122
|
-
description: 'Output directory for reports',
|
|
123
|
-
type: 'string',
|
|
124
|
-
})
|
|
125
|
-
.option('output-file', {
|
|
126
|
-
alias: ['of', 'file'],
|
|
127
|
-
description: 'Custom filename for reporter output (use with single reporter only)',
|
|
128
|
-
requiresArg: true,
|
|
129
|
-
type: 'string',
|
|
130
|
-
})
|
|
131
|
-
.option('iterations', {
|
|
132
|
-
alias: 'i',
|
|
133
|
-
description: 'Number of iterations per benchmark',
|
|
134
|
-
type: 'number',
|
|
135
|
-
})
|
|
136
|
-
.option('time', {
|
|
137
|
-
alias: 't',
|
|
138
|
-
description: 'Time budget per benchmark in milliseconds',
|
|
139
|
-
type: 'number',
|
|
140
|
-
})
|
|
141
|
-
.option('warmup', {
|
|
142
|
-
alias: ['w', 'warm'],
|
|
143
|
-
description: 'Number of warmup iterations',
|
|
144
|
-
type: 'number',
|
|
145
|
-
})
|
|
146
|
-
.option('limit-by', {
|
|
147
|
-
alias: ['l', 'limit'],
|
|
148
|
-
choices: ['time', 'iterations', 'any', 'all'],
|
|
149
|
-
description: 'How to limit benchmarks: time (time budget), iterations (sample count), any (either threshold), all (both thresholds)',
|
|
150
|
-
type: 'string',
|
|
151
|
-
})
|
|
152
|
-
.option('bail', {
|
|
153
|
-
alias: 'b',
|
|
154
|
-
defaultDescription: String(run_js_1.RUN_COMMAND_DEFAULTS.bail),
|
|
155
|
-
description: 'Stop on first failure',
|
|
156
|
-
type: 'boolean',
|
|
157
|
-
})
|
|
158
|
-
.option('exclude', {
|
|
159
|
-
alias: 'X',
|
|
160
|
-
array: true,
|
|
161
|
-
description: 'Exclude patterns (comma-separated)',
|
|
162
|
-
type: 'string',
|
|
163
|
-
})
|
|
164
|
-
.option('timeout', {
|
|
165
|
-
description: 'Timeout per benchmark in milliseconds',
|
|
166
|
-
type: 'number',
|
|
167
|
-
})
|
|
168
|
-
.option('quiet', {
|
|
169
|
-
alias: 'q',
|
|
170
|
-
defaultDescription: String(run_js_1.RUN_COMMAND_DEFAULTS.quiet),
|
|
171
|
-
description: 'Minimal output',
|
|
172
|
-
type: 'boolean',
|
|
173
|
-
})
|
|
174
|
-
.option('tag', {
|
|
175
|
-
array: true,
|
|
176
|
-
description: 'Include only benchmarks with any of these tags',
|
|
177
|
-
type: 'string',
|
|
178
|
-
})
|
|
179
|
-
.option('exclude-tag', {
|
|
180
|
-
alias: 'T',
|
|
181
|
-
array: true,
|
|
182
|
-
description: 'Exclude benchmarks with any of these tags',
|
|
183
|
-
type: 'string',
|
|
184
|
-
})
|
|
185
|
-
.option('engine', {
|
|
186
|
-
alias: 'e',
|
|
187
|
-
choices: Object.values(constants_js_1.Engines),
|
|
188
|
-
defaultDescription: constants_js_1.DEFAULT_ENGINE,
|
|
189
|
-
description: 'Benchmark engine: tinybench (default) or accurate (requires --allow-natives-syntax)',
|
|
190
|
-
type: 'string',
|
|
191
|
-
})
|
|
192
|
-
.option('json-pretty', {
|
|
193
|
-
defaultDescription: 'false',
|
|
194
|
-
description: 'Pretty-print JSON output (only affects json reporter)',
|
|
195
|
-
type: 'boolean',
|
|
196
|
-
})
|
|
197
|
-
.example([
|
|
198
|
-
['$0 run', 'Run benchmarks in current directory and bench/'],
|
|
199
|
-
['$0 run benchmarks/', 'Run all benchmarks in a directory'],
|
|
200
|
-
['$0 run src/perf/', 'Run benchmarks in specific directory'],
|
|
201
|
-
['$0 run "src/**/*.bench.js"', 'Run specific glob pattern'],
|
|
202
|
-
['$0 run file1.bench.js file2.bench.js', 'Run specific files'],
|
|
203
|
-
['$0 run benchmarks/ tests/perf/', 'Run multiple directories'],
|
|
204
|
-
['$0 run -r json -r csv', 'Use multiple reporters'],
|
|
205
|
-
['$0 run --iterations 1000', 'Set iteration count'],
|
|
206
|
-
['$0 run --engine accurate', 'Use high-accuracy engine'],
|
|
207
|
-
['$0 run --bail', 'Stop on first failure'],
|
|
208
|
-
])
|
|
209
|
-
.check((argv) => {
|
|
210
|
-
if (argv.reporter &&
|
|
211
|
-
argv.reporter.length > 1 &&
|
|
212
|
-
argv['output-file']) {
|
|
213
|
-
throw new Error('--output-file can only be used with a single reporter. Use --output <dir> for multiple reporters.');
|
|
214
|
-
}
|
|
215
|
-
return true;
|
|
216
|
-
}), async (argv) => {
|
|
217
|
-
const context = await createCliContext(argv, abortController, argv.engine);
|
|
218
|
-
const exitCode = await (0, run_js_1.handleRunCommand)(context, {
|
|
219
|
-
bail: argv.bail,
|
|
220
|
-
config: argv.config,
|
|
221
|
-
cwd: argv.cwd,
|
|
222
|
-
engine: argv.engine,
|
|
223
|
-
exclude: argv.exclude,
|
|
224
|
-
excludeTags: argv['exclude-tag'],
|
|
225
|
-
iterations: argv.iterations,
|
|
226
|
-
json: argv.json,
|
|
227
|
-
jsonPretty: argv['json-pretty'],
|
|
228
|
-
noColor: argv.noColor,
|
|
229
|
-
outputDir: argv.output,
|
|
230
|
-
outputFile: argv['output-file'],
|
|
231
|
-
pattern: argv.pattern,
|
|
232
|
-
progress: argv.progress,
|
|
233
|
-
quiet: argv.quiet,
|
|
234
|
-
reporters: argv.reporter,
|
|
235
|
-
tags: argv.tag,
|
|
236
|
-
time: argv.time,
|
|
237
|
-
timeout: argv.timeout,
|
|
238
|
-
verbose: argv.verbose,
|
|
239
|
-
warmup: argv.warmup,
|
|
240
|
-
});
|
|
241
|
-
process.exit(exitCode);
|
|
242
|
-
})
|
|
243
|
-
.command('history', 'View and manage benchmark history', (yargs) => yargs
|
|
244
|
-
.command('list', 'List recent benchmark runs', (yargs) => yargs
|
|
245
|
-
.option('since', {
|
|
246
|
-
description: 'Show runs since date (ISO 8601 or relative like "1 week ago")',
|
|
247
|
-
type: 'string',
|
|
248
|
-
})
|
|
249
|
-
.option('until', {
|
|
250
|
-
description: 'Show runs until date (ISO 8601 or relative like "1 day ago")',
|
|
251
|
-
type: 'string',
|
|
252
|
-
})
|
|
253
|
-
.option('pattern', {
|
|
254
|
-
description: 'Filter by benchmark name pattern',
|
|
255
|
-
type: 'string',
|
|
256
|
-
})
|
|
257
|
-
.option('tag', {
|
|
258
|
-
alias: 't',
|
|
259
|
-
array: true,
|
|
260
|
-
description: 'Filter by tags (comma-separated)',
|
|
261
|
-
type: 'string',
|
|
262
|
-
})
|
|
263
|
-
.option('limit', {
|
|
264
|
-
defaultDescription: '10',
|
|
265
|
-
description: 'Maximum number of results',
|
|
266
|
-
type: 'number',
|
|
267
|
-
})
|
|
268
|
-
.option('format', {
|
|
269
|
-
choices: ['human', 'json', 'csv'],
|
|
270
|
-
defaultDescription: 'human',
|
|
271
|
-
description: 'Output format',
|
|
272
|
-
type: 'string',
|
|
273
|
-
})
|
|
274
|
-
.example([
|
|
275
|
-
['$0 history list', 'List recent benchmark runs'],
|
|
276
|
-
[
|
|
277
|
-
'$0 history list --since "1 week ago"',
|
|
278
|
-
'List runs from last week',
|
|
279
|
-
],
|
|
280
|
-
['$0 history list --limit 20', 'List 20 most recent runs'],
|
|
281
|
-
['$0 history list --format json', 'List runs in JSON format'],
|
|
282
|
-
]), async (argv) => {
|
|
283
|
-
const context = await createCliContext(argv, abortController);
|
|
284
|
-
const exitCode = await (0, history_js_1.handleListCommand)(context, {
|
|
285
|
-
cwd: argv.cwd,
|
|
286
|
-
format: argv.format,
|
|
287
|
-
limit: argv.limit,
|
|
288
|
-
pattern: argv.pattern,
|
|
289
|
-
since: argv.since,
|
|
290
|
-
tags: argv.tag,
|
|
291
|
-
until: argv.until,
|
|
292
|
-
verbose: argv.verbose,
|
|
293
|
-
});
|
|
294
|
-
process.exit(exitCode);
|
|
295
|
-
})
|
|
296
|
-
.command('show <run-id>', 'Show detailed results for a specific run', (yargs) => yargs
|
|
297
|
-
.positional('run-id', {
|
|
298
|
-
demandOption: true,
|
|
299
|
-
describe: 'ID of the benchmark run to show',
|
|
300
|
-
type: 'string',
|
|
301
|
-
})
|
|
302
|
-
.option('format', {
|
|
303
|
-
choices: ['human', 'json', 'csv'],
|
|
304
|
-
defaultDescription: 'human',
|
|
305
|
-
description: 'Output format',
|
|
306
|
-
type: 'string',
|
|
307
|
-
})
|
|
308
|
-
.example([
|
|
309
|
-
[
|
|
310
|
-
'$0 history show abc123',
|
|
311
|
-
'Show detailed results for run abc123',
|
|
312
|
-
],
|
|
313
|
-
[
|
|
314
|
-
'$0 history show abc123 --format json',
|
|
315
|
-
'Show run in JSON format',
|
|
316
|
-
],
|
|
317
|
-
]), async (argv) => {
|
|
318
|
-
const context = await createCliContext(argv, abortController);
|
|
319
|
-
const exitCode = await (0, history_js_1.handleShowCommand)(context, {
|
|
320
|
-
cwd: argv.cwd,
|
|
321
|
-
format: argv.format,
|
|
322
|
-
runId: argv['run-id'],
|
|
323
|
-
verbose: argv.verbose,
|
|
324
|
-
});
|
|
325
|
-
process.exit(exitCode);
|
|
326
|
-
})
|
|
327
|
-
.command('compare <run-id1> <run-id2>', 'Compare two benchmark runs', (yargs) => yargs
|
|
328
|
-
.positional('run-id1', {
|
|
329
|
-
demandOption: true,
|
|
330
|
-
describe: 'ID of the first benchmark run',
|
|
331
|
-
type: 'string',
|
|
332
|
-
})
|
|
333
|
-
.positional('run-id2', {
|
|
334
|
-
demandOption: true,
|
|
335
|
-
describe: 'ID of the second benchmark run',
|
|
336
|
-
type: 'string',
|
|
337
|
-
})
|
|
338
|
-
.option('format', {
|
|
339
|
-
choices: ['human', 'json'],
|
|
340
|
-
defaultDescription: 'human',
|
|
341
|
-
description: 'Output format',
|
|
342
|
-
type: 'string',
|
|
343
|
-
})
|
|
344
|
-
.example([
|
|
345
|
-
['$0 history compare abc123 def456', 'Compare two runs'],
|
|
346
|
-
[
|
|
347
|
-
'$0 history compare abc123 def456 --format json',
|
|
348
|
-
'Compare in JSON format',
|
|
349
|
-
],
|
|
350
|
-
]), async (argv) => {
|
|
351
|
-
const context = await createCliContext(argv, abortController);
|
|
352
|
-
const exitCode = await (0, history_js_1.handleCompareCommand)(context, {
|
|
353
|
-
cwd: argv.cwd,
|
|
354
|
-
format: argv.format,
|
|
355
|
-
runId1: argv['run-id1'],
|
|
356
|
-
runId2: argv['run-id2'],
|
|
357
|
-
verbose: argv.verbose,
|
|
358
|
-
});
|
|
359
|
-
process.exit(exitCode);
|
|
360
|
-
})
|
|
361
|
-
.command('trends [pattern]', 'Show performance trends over time', (yargs) => yargs
|
|
362
|
-
.positional('pattern', {
|
|
363
|
-
describe: 'Filter by benchmark name pattern',
|
|
364
|
-
type: 'string',
|
|
365
|
-
})
|
|
366
|
-
.option('since', {
|
|
367
|
-
description: 'Show trends since date (ISO 8601 or relative like "1 week ago")',
|
|
368
|
-
type: 'string',
|
|
369
|
-
})
|
|
370
|
-
.option('until', {
|
|
371
|
-
description: 'Show trends until date (ISO 8601 or relative like "1 day ago")',
|
|
372
|
-
type: 'string',
|
|
373
|
-
})
|
|
374
|
-
.option('tag', {
|
|
375
|
-
alias: 't',
|
|
376
|
-
array: true,
|
|
377
|
-
description: 'Filter by tags (comma-separated)',
|
|
378
|
-
type: 'string',
|
|
379
|
-
})
|
|
380
|
-
.option('limit', {
|
|
381
|
-
description: 'Maximum number of runs to analyze',
|
|
382
|
-
type: 'number',
|
|
383
|
-
})
|
|
384
|
-
.option('all', {
|
|
385
|
-
alias: 'a',
|
|
386
|
-
defaultDescription: 'false',
|
|
387
|
-
description: 'Analyze all runs (ignore limit)',
|
|
388
|
-
type: 'boolean',
|
|
389
|
-
})
|
|
390
|
-
.option('format', {
|
|
391
|
-
choices: ['human', 'json'],
|
|
392
|
-
defaultDescription: 'human',
|
|
393
|
-
description: 'Output format',
|
|
394
|
-
type: 'string',
|
|
395
|
-
})
|
|
396
|
-
.example([
|
|
397
|
-
[
|
|
398
|
-
'$0 history trends',
|
|
399
|
-
'Show performance trends for all benchmarks',
|
|
400
|
-
],
|
|
401
|
-
[
|
|
402
|
-
'$0 history trends --since "1 month ago"',
|
|
403
|
-
'Show trends from last month',
|
|
404
|
-
],
|
|
405
|
-
[
|
|
406
|
-
'$0 history trends "array-*"',
|
|
407
|
-
'Show trends for array benchmarks',
|
|
408
|
-
],
|
|
409
|
-
[
|
|
410
|
-
'$0 history trends --format json',
|
|
411
|
-
'Output trends in JSON format',
|
|
412
|
-
],
|
|
413
|
-
]), async (argv) => {
|
|
414
|
-
const context = await createCliContext(argv, abortController);
|
|
415
|
-
const exitCode = await (0, history_js_1.handleTrendsCommand)(context, {
|
|
416
|
-
all: argv.all,
|
|
417
|
-
cwd: argv.cwd,
|
|
418
|
-
format: argv.format,
|
|
419
|
-
limit: argv.limit,
|
|
420
|
-
pattern: argv.pattern,
|
|
421
|
-
since: argv.since,
|
|
422
|
-
tags: argv.tag,
|
|
423
|
-
until: argv.until,
|
|
424
|
-
verbose: argv.verbose,
|
|
425
|
-
});
|
|
426
|
-
process.exit(exitCode);
|
|
427
|
-
})
|
|
428
|
-
.command('clean', 'Clean up old benchmark history', (yargs) => yargs
|
|
429
|
-
.option('max-age', {
|
|
430
|
-
description: 'Remove runs older than this many days',
|
|
431
|
-
type: 'number',
|
|
432
|
-
})
|
|
433
|
-
.option('max-runs', {
|
|
434
|
-
description: 'Keep only this many most recent runs',
|
|
435
|
-
type: 'number',
|
|
436
|
-
})
|
|
437
|
-
.option('max-size', {
|
|
438
|
-
description: 'Keep history under this size in bytes',
|
|
439
|
-
type: 'number',
|
|
440
|
-
})
|
|
441
|
-
.option('yes', {
|
|
442
|
-
alias: 'y',
|
|
443
|
-
description: 'Confirm cleanup without prompting',
|
|
444
|
-
type: 'boolean',
|
|
445
|
-
})
|
|
446
|
-
.option('quiet', {
|
|
447
|
-
default: false,
|
|
448
|
-
description: 'Minimal output',
|
|
449
|
-
type: 'boolean',
|
|
450
|
-
})
|
|
451
|
-
.check((argv) => {
|
|
452
|
-
if (!argv['max-age'] &&
|
|
453
|
-
!argv['max-runs'] &&
|
|
454
|
-
!argv['max-size']) {
|
|
455
|
-
throw new Error('At least one cleanup criterion must be specified (--max-age, --max-runs, or --max-size)');
|
|
456
|
-
}
|
|
457
|
-
return true;
|
|
458
|
-
})
|
|
459
|
-
.example([
|
|
460
|
-
[
|
|
461
|
-
'$0 history clean --max-runs 50 --yes',
|
|
462
|
-
'Keep only latest 50 runs',
|
|
463
|
-
],
|
|
464
|
-
[
|
|
465
|
-
'$0 history clean --max-age 30',
|
|
466
|
-
'Preview removing runs older than 30 days',
|
|
467
|
-
],
|
|
468
|
-
[
|
|
469
|
-
'$0 history clean --max-size 10485760',
|
|
470
|
-
'Keep history under 10MB',
|
|
471
|
-
],
|
|
472
|
-
]), async (argv) => {
|
|
473
|
-
const context = await createCliContext(argv, abortController);
|
|
474
|
-
const exitCode = await (0, history_js_1.handleCleanCommand)(context, {
|
|
475
|
-
confirm: argv.yes,
|
|
476
|
-
cwd: argv.cwd,
|
|
477
|
-
maxAge: argv['max-age'],
|
|
478
|
-
maxRuns: argv['max-runs'],
|
|
479
|
-
maxSize: argv['max-size'],
|
|
480
|
-
quiet: argv.quiet,
|
|
481
|
-
verbose: argv.verbose,
|
|
482
|
-
});
|
|
483
|
-
process.exit(exitCode);
|
|
484
|
-
})
|
|
485
|
-
.command('export', 'Export benchmark history to a file', (yargs) => yargs
|
|
486
|
-
.option('format', {
|
|
487
|
-
choices: ['json', 'csv'],
|
|
488
|
-
defaultDescription: 'json',
|
|
489
|
-
description: 'Export format',
|
|
490
|
-
type: 'string',
|
|
491
|
-
})
|
|
492
|
-
.option('output', {
|
|
493
|
-
alias: 'o',
|
|
494
|
-
demandOption: true,
|
|
495
|
-
description: 'Output file path',
|
|
496
|
-
type: 'string',
|
|
497
|
-
})
|
|
498
|
-
.option('since', {
|
|
499
|
-
description: 'Export runs since date',
|
|
500
|
-
type: 'string',
|
|
501
|
-
})
|
|
502
|
-
.option('until', {
|
|
503
|
-
description: 'Export runs until date',
|
|
504
|
-
type: 'string',
|
|
505
|
-
})
|
|
506
|
-
.example([
|
|
507
|
-
[
|
|
508
|
-
'$0 history export -o history.json',
|
|
509
|
-
'Export all history to JSON',
|
|
510
|
-
],
|
|
511
|
-
[
|
|
512
|
-
'$0 history export -o history.csv --format csv',
|
|
513
|
-
'Export to CSV',
|
|
514
|
-
],
|
|
515
|
-
[
|
|
516
|
-
'$0 history export -o recent.json --since "1 week ago"',
|
|
517
|
-
'Export recent runs',
|
|
518
|
-
],
|
|
519
|
-
]), async (argv) => {
|
|
520
|
-
const context = await createCliContext(argv, abortController);
|
|
521
|
-
const exitCode = await (0, history_js_1.handleExportCommand)(context, {
|
|
522
|
-
cwd: argv.cwd,
|
|
523
|
-
format: argv.format,
|
|
524
|
-
outputPath: argv.output,
|
|
525
|
-
quiet: Boolean(argv.quiet),
|
|
526
|
-
since: argv.since,
|
|
527
|
-
until: argv.until,
|
|
528
|
-
verbose: argv.verbose,
|
|
529
|
-
});
|
|
530
|
-
process.exitCode = exitCode;
|
|
531
|
-
})
|
|
532
|
-
.demandCommand(1, 'You must specify a history subcommand')
|
|
533
|
-
.strict()
|
|
534
|
-
.example([
|
|
535
|
-
['$0 history list', 'List recent benchmark runs'],
|
|
536
|
-
['$0 history show <run-id>', 'Show detailed results'],
|
|
537
|
-
['$0 history compare <run-id1> <run-id2>', 'Compare two runs'],
|
|
538
|
-
['$0 history trends', 'Show performance trends'],
|
|
539
|
-
['$0 history clean --max-runs 50', 'Keep only latest 50 runs'],
|
|
540
|
-
['$0 history export -o data.json', 'Export history'],
|
|
541
|
-
]))
|
|
542
|
-
.command('baseline', 'Manage performance baselines', (yargs) => {
|
|
543
|
-
return yargs
|
|
544
|
-
.command('set <name>', 'Save a benchmark run as a baseline', (yargs) => {
|
|
545
|
-
return yargs
|
|
546
|
-
.positional('name', {
|
|
547
|
-
describe: 'Name for the baseline',
|
|
548
|
-
type: 'string',
|
|
549
|
-
})
|
|
550
|
-
.option('run-id', {
|
|
551
|
-
description: 'Specific run ID to save (default: most recent)',
|
|
552
|
-
type: 'string',
|
|
553
|
-
})
|
|
554
|
-
.option('commit', {
|
|
555
|
-
description: 'Git commit SHA (40 characters)',
|
|
556
|
-
type: 'string',
|
|
557
|
-
})
|
|
558
|
-
.option('branch', {
|
|
559
|
-
description: 'Git branch name',
|
|
560
|
-
type: 'string',
|
|
561
|
-
})
|
|
562
|
-
.option('default', {
|
|
563
|
-
defaultDescription: 'false',
|
|
564
|
-
description: 'Set as default baseline',
|
|
565
|
-
type: 'boolean',
|
|
566
|
-
})
|
|
567
|
-
.example([
|
|
568
|
-
[
|
|
569
|
-
'$0 baseline set production-v1.0',
|
|
570
|
-
'Save most recent run as baseline',
|
|
571
|
-
],
|
|
572
|
-
['$0 baseline set v1.0 --default', 'Save and set as default'],
|
|
573
|
-
[
|
|
574
|
-
'$0 baseline set v1.0 --commit abc123...',
|
|
575
|
-
'Save with commit info',
|
|
576
|
-
],
|
|
577
|
-
]);
|
|
578
|
-
}, async (argv) => {
|
|
579
|
-
const context = await createCliContext(argv, abortController);
|
|
580
|
-
const exitCode = await (0, baseline_js_1.handleSetCommand)(context, {
|
|
581
|
-
branch: argv.branch,
|
|
582
|
-
commit: argv.commit,
|
|
583
|
-
cwd: argv.cwd,
|
|
584
|
-
default: argv.default,
|
|
585
|
-
name: String(argv.name),
|
|
586
|
-
quiet: Boolean(argv.quiet),
|
|
587
|
-
runId: argv['run-id'],
|
|
588
|
-
verbose: argv.verbose,
|
|
589
|
-
});
|
|
590
|
-
process.exit(exitCode);
|
|
591
|
-
})
|
|
592
|
-
.command('list', 'List all saved baselines', (yargs) => {
|
|
593
|
-
return yargs
|
|
594
|
-
.option('format', {
|
|
595
|
-
choices: ['human', 'json'],
|
|
596
|
-
defaultDescription: 'human',
|
|
597
|
-
description: 'Output format',
|
|
598
|
-
type: 'string',
|
|
599
|
-
})
|
|
600
|
-
.example([
|
|
601
|
-
['$0 baseline list', 'List all baselines'],
|
|
602
|
-
['$0 baseline list --format json', 'List in JSON format'],
|
|
603
|
-
]);
|
|
604
|
-
}, async (argv) => {
|
|
605
|
-
const context = await createCliContext(argv, abortController);
|
|
606
|
-
const exitCode = await (0, baseline_js_1.handleListCommand)(context, {
|
|
607
|
-
cwd: argv.cwd,
|
|
608
|
-
format: argv.format,
|
|
609
|
-
quiet: Boolean(argv.quiet),
|
|
610
|
-
verbose: argv.verbose,
|
|
611
|
-
});
|
|
612
|
-
process.exit(exitCode);
|
|
613
|
-
})
|
|
614
|
-
.command('show <name>', 'Show baseline details', (yargs) => {
|
|
615
|
-
return yargs
|
|
616
|
-
.positional('name', {
|
|
617
|
-
describe: 'Baseline name to show',
|
|
618
|
-
type: 'string',
|
|
619
|
-
})
|
|
620
|
-
.option('format', {
|
|
621
|
-
choices: ['human', 'json'],
|
|
622
|
-
defaultDescription: 'human',
|
|
623
|
-
description: 'Output format',
|
|
624
|
-
type: 'string',
|
|
625
|
-
})
|
|
626
|
-
.example([
|
|
627
|
-
['$0 baseline show production-v1.0', 'Show baseline details'],
|
|
628
|
-
[
|
|
629
|
-
'$0 baseline show v1.0 --format json',
|
|
630
|
-
'Show in JSON format',
|
|
631
|
-
],
|
|
632
|
-
]);
|
|
633
|
-
}, async (argv) => {
|
|
634
|
-
const context = await createCliContext(argv, abortController);
|
|
635
|
-
const exitCode = await (0, baseline_js_1.handleShowCommand)(context, {
|
|
636
|
-
cwd: argv.cwd,
|
|
637
|
-
format: argv.format,
|
|
638
|
-
name: String(argv.name),
|
|
639
|
-
quiet: Boolean(argv.quiet),
|
|
640
|
-
verbose: argv.verbose,
|
|
641
|
-
});
|
|
642
|
-
process.exit(exitCode);
|
|
643
|
-
})
|
|
644
|
-
.command('delete <name>', 'Delete a baseline', (yargs) => {
|
|
645
|
-
return yargs
|
|
646
|
-
.positional('name', {
|
|
647
|
-
describe: 'Baseline name to delete',
|
|
648
|
-
type: 'string',
|
|
649
|
-
})
|
|
650
|
-
.example([
|
|
651
|
-
['$0 baseline delete old-baseline', 'Delete a baseline'],
|
|
652
|
-
]);
|
|
653
|
-
}, async (argv) => {
|
|
654
|
-
const context = await createCliContext(argv, abortController);
|
|
655
|
-
const exitCode = await (0, baseline_js_1.handleDeleteCommand)(context, {
|
|
656
|
-
cwd: argv.cwd,
|
|
657
|
-
name: String(argv.name),
|
|
658
|
-
quiet: Boolean(argv.quiet),
|
|
659
|
-
verbose: argv.verbose,
|
|
660
|
-
});
|
|
661
|
-
process.exit(exitCode);
|
|
662
|
-
})
|
|
663
|
-
.command('analyze', 'Analyze history and suggest performance budgets', (yargs) => {
|
|
664
|
-
return yargs
|
|
665
|
-
.option('runs', {
|
|
666
|
-
defaultDescription: '10',
|
|
667
|
-
description: 'Number of recent runs to analyze',
|
|
668
|
-
type: 'number',
|
|
669
|
-
})
|
|
670
|
-
.option('confidence', {
|
|
671
|
-
defaultDescription: '0.95',
|
|
672
|
-
description: 'Confidence level (0.5-0.999, default 0.95)',
|
|
673
|
-
type: 'number',
|
|
674
|
-
})
|
|
675
|
-
.example([
|
|
676
|
-
[
|
|
677
|
-
'$0 baseline analyze',
|
|
678
|
-
'Analyze last 10 runs with 95% confidence',
|
|
679
|
-
],
|
|
680
|
-
['$0 baseline analyze --runs 20', 'Analyze last 20 runs'],
|
|
681
|
-
[
|
|
682
|
-
'$0 baseline analyze --confidence 0.90',
|
|
683
|
-
'Use 90% confidence level',
|
|
684
|
-
],
|
|
685
|
-
]);
|
|
686
|
-
}, async (argv) => {
|
|
687
|
-
const context = await createCliContext(argv, abortController);
|
|
688
|
-
const exitCode = await (0, baseline_js_1.handleAnalyzeCommand)(context, {
|
|
689
|
-
confidence: argv.confidence,
|
|
690
|
-
cwd: argv.cwd,
|
|
691
|
-
quiet: Boolean(argv.quiet),
|
|
692
|
-
runs: argv.runs,
|
|
693
|
-
verbose: argv.verbose,
|
|
694
|
-
});
|
|
695
|
-
process.exit(exitCode);
|
|
696
|
-
})
|
|
697
|
-
.demandCommand(1, 'You must specify a baseline subcommand')
|
|
698
|
-
.strict()
|
|
699
|
-
.example([
|
|
700
|
-
['$0 baseline set production-v1.0', 'Save current run as baseline'],
|
|
701
|
-
['$0 baseline list', 'List all baselines'],
|
|
702
|
-
['$0 baseline show production-v1.0', 'Show baseline details'],
|
|
703
|
-
['$0 baseline delete old-baseline', 'Delete a baseline'],
|
|
704
|
-
['$0 baseline analyze', 'Suggest budgets from history'],
|
|
705
|
-
]);
|
|
706
|
-
})
|
|
707
|
-
.command('init [type]', 'Initialize a new benchmark project', (yargs) => {
|
|
708
|
-
return yargs
|
|
709
|
-
.positional('type', {
|
|
710
|
-
choices: ['basic', 'advanced', 'library'],
|
|
711
|
-
defaultDescription: 'basic',
|
|
712
|
-
describe: 'Type of project to initialize',
|
|
713
|
-
type: 'string',
|
|
714
|
-
})
|
|
715
|
-
.option('examples', {
|
|
716
|
-
defaultDescription: 'true',
|
|
717
|
-
description: 'Include example benchmark files',
|
|
718
|
-
type: 'boolean',
|
|
719
|
-
})
|
|
720
|
-
.option('config-type', {
|
|
721
|
-
choices: ['json', 'yaml', 'js', 'ts'],
|
|
722
|
-
defaultDescription: 'json',
|
|
723
|
-
description: 'Configuration file format',
|
|
724
|
-
type: 'string',
|
|
725
|
-
})
|
|
726
|
-
.option('force', {
|
|
727
|
-
defaultDescription: 'false',
|
|
728
|
-
description: 'Overwrite existing files',
|
|
729
|
-
type: 'boolean',
|
|
730
|
-
})
|
|
731
|
-
.option('yes', {
|
|
732
|
-
alias: 'y',
|
|
733
|
-
defaultDescription: 'false',
|
|
734
|
-
description: 'Accept all prompts automatically',
|
|
735
|
-
type: 'boolean',
|
|
736
|
-
})
|
|
737
|
-
.option('quiet', {
|
|
738
|
-
alias: 'q',
|
|
739
|
-
defaultDescription: 'false',
|
|
740
|
-
description: 'Minimal output',
|
|
741
|
-
type: 'boolean',
|
|
742
|
-
})
|
|
743
|
-
.example([
|
|
744
|
-
['$0 init', 'Initialize a basic project'],
|
|
745
|
-
[
|
|
746
|
-
'$0 init advanced --config-type ts',
|
|
747
|
-
'Initialize advanced project with TypeScript config',
|
|
748
|
-
],
|
|
749
|
-
[
|
|
750
|
-
'$0 init library --no-examples',
|
|
751
|
-
'Initialize library project without examples',
|
|
752
|
-
],
|
|
753
|
-
]);
|
|
754
|
-
}, async (argv) => {
|
|
755
|
-
const context = await createCliContext(argv, abortController);
|
|
756
|
-
const exitCode = await (0, init_js_1.handleInitCommand)(context, {
|
|
757
|
-
configType: argv['config-type'],
|
|
758
|
-
cwd: argv.cwd,
|
|
759
|
-
examples: argv.examples,
|
|
760
|
-
force: argv.force,
|
|
761
|
-
quiet: argv.quiet,
|
|
762
|
-
type: argv.type,
|
|
763
|
-
verbose: argv.verbose,
|
|
764
|
-
yes: argv.yes,
|
|
765
|
-
});
|
|
766
|
-
process.exitCode = exitCode;
|
|
767
|
-
})
|
|
768
|
-
.command(['analyze [command]', 'profile [command]'], 'Analyze code execution and identify benchmark candidates', (yargs) => {
|
|
769
|
-
return yargs
|
|
770
|
-
.positional('command', {
|
|
771
|
-
description: 'Command to analyze (e.g., "npm test")',
|
|
772
|
-
type: 'string',
|
|
773
|
-
})
|
|
774
|
-
.option('input', {
|
|
775
|
-
alias: 'i',
|
|
776
|
-
description: 'Path to existing *.cpuprofile file',
|
|
777
|
-
type: 'string',
|
|
778
|
-
})
|
|
779
|
-
.option('filter-file', {
|
|
780
|
-
description: 'Filter functions by file glob pattern',
|
|
781
|
-
type: 'string',
|
|
782
|
-
})
|
|
783
|
-
.option('min-percent', {
|
|
784
|
-
alias: ['m', 'min'],
|
|
785
|
-
default: 0.5,
|
|
786
|
-
description: 'Minimum execution percentage to show',
|
|
787
|
-
type: 'number',
|
|
788
|
-
})
|
|
789
|
-
.option('top', {
|
|
790
|
-
alias: 'n',
|
|
791
|
-
default: 25,
|
|
792
|
-
description: 'Number of top functions to show',
|
|
793
|
-
type: 'number',
|
|
794
|
-
})
|
|
795
|
-
.option('group-by-file', {
|
|
796
|
-
default: false,
|
|
797
|
-
description: 'Group results by file',
|
|
798
|
-
type: 'boolean',
|
|
799
|
-
})
|
|
800
|
-
.check((argv) => {
|
|
801
|
-
if (!argv.command && !argv.input) {
|
|
802
|
-
throw new Error('Either [command] or --input must be provided');
|
|
803
|
-
}
|
|
804
|
-
return true;
|
|
805
|
-
});
|
|
806
|
-
}, async (argv) => {
|
|
807
|
-
// Context not needed for analyze command currently
|
|
808
|
-
const context = {};
|
|
809
|
-
const options = {
|
|
810
|
-
color: !argv.noColor,
|
|
811
|
-
command: argv.command,
|
|
812
|
-
cwd: argv.cwd || process.cwd(),
|
|
813
|
-
filterFile: argv.filterFile,
|
|
814
|
-
groupByFile: argv.groupByFile,
|
|
815
|
-
input: argv.input,
|
|
816
|
-
minPercent: argv.minPercent,
|
|
817
|
-
top: argv.top,
|
|
818
|
-
};
|
|
819
|
-
process.exitCode = await (0, analyze_js_1.handleAnalyzeCommand)(context, options);
|
|
820
|
-
})
|
|
821
|
-
.command('test <framework> [files..]', 'Run test files as benchmarks (captures tests from Jest, Mocha, node:test, or AVA)', (yargs) => {
|
|
822
|
-
return yargs
|
|
823
|
-
.positional('framework', {
|
|
824
|
-
choices: ['ava', 'jest', 'mocha', 'node-test'],
|
|
825
|
-
demandOption: true,
|
|
826
|
-
describe: 'Test framework to use',
|
|
827
|
-
nargs: 1,
|
|
828
|
-
type: 'string',
|
|
829
|
-
})
|
|
830
|
-
.positional('files', {
|
|
831
|
-
array: true,
|
|
832
|
-
describe: 'Test file paths or glob patterns',
|
|
833
|
-
type: 'string',
|
|
834
|
-
})
|
|
835
|
-
.option('iterations', {
|
|
836
|
-
alias: 'i',
|
|
837
|
-
default: 100,
|
|
838
|
-
description: 'Number of iterations per test',
|
|
839
|
-
type: 'number',
|
|
840
|
-
})
|
|
841
|
-
.option('warmup', {
|
|
842
|
-
alias: 'w',
|
|
843
|
-
default: 5,
|
|
844
|
-
description: 'Number of warmup iterations',
|
|
845
|
-
type: 'number',
|
|
846
|
-
})
|
|
847
|
-
.option('bail', {
|
|
848
|
-
alias: 'b',
|
|
849
|
-
default: false,
|
|
850
|
-
description: 'Stop on first failure',
|
|
851
|
-
type: 'boolean',
|
|
852
|
-
})
|
|
853
|
-
.option('quiet', {
|
|
854
|
-
alias: 'q',
|
|
855
|
-
default: false,
|
|
856
|
-
description: 'Minimal output',
|
|
857
|
-
type: 'boolean',
|
|
858
|
-
})
|
|
859
|
-
.example([
|
|
860
|
-
['$0 test mocha test/*.spec.js', 'Run Mocha tests as benchmarks'],
|
|
861
|
-
[
|
|
862
|
-
'$0 test node-test test/*.test.js',
|
|
863
|
-
'Run node:test tests as benchmarks',
|
|
864
|
-
],
|
|
865
|
-
[
|
|
866
|
-
'$0 test ava test/*.js --iterations 500',
|
|
867
|
-
'Run AVA tests with 500 iterations',
|
|
868
|
-
],
|
|
869
|
-
[
|
|
870
|
-
'$0 test mocha test/unit.spec.js --json',
|
|
871
|
-
'Output results as JSON',
|
|
872
|
-
],
|
|
873
|
-
]);
|
|
874
|
-
}, async (argv) => {
|
|
875
|
-
const context = await createCliContext(argv, abortController);
|
|
876
|
-
const options = {
|
|
877
|
-
bail: argv.bail,
|
|
878
|
-
cwd: argv.cwd,
|
|
879
|
-
framework: argv.framework,
|
|
880
|
-
iterations: argv.iterations,
|
|
881
|
-
json: argv.json,
|
|
882
|
-
noColor: argv.noColor,
|
|
883
|
-
pattern: argv.files,
|
|
884
|
-
quiet: argv.quiet,
|
|
885
|
-
verbose: argv.verbose,
|
|
886
|
-
warmup: argv.warmup,
|
|
887
|
-
};
|
|
888
|
-
const exitCode = await (0, test_js_1.handleTestCommand)(context, options);
|
|
889
|
-
process.exit(exitCode);
|
|
890
|
-
})
|
|
891
|
-
.fail((msg, err, yargs) => {
|
|
892
|
-
if (err) {
|
|
893
|
-
console.error('Error:', err.message);
|
|
894
|
-
if (process.env.DEBUG) {
|
|
895
|
-
console.error(err.stack);
|
|
896
|
-
}
|
|
897
|
-
// Show help for file discovery errors (similar to usage errors)
|
|
898
|
-
if ((0, index_js_2.isModestBenchError)(err) &&
|
|
899
|
-
err.code === constants_js_1.ErrorCodes.FILE_DISCOVERY_FAILED) {
|
|
900
|
-
console.error();
|
|
901
|
-
yargs.showHelp();
|
|
902
|
-
process.exit(constants_js_1.ExitCodes.DISCOVERY_ERROR);
|
|
903
|
-
}
|
|
904
|
-
process.exit(constants_js_1.ExitCodes.RUNTIME_ERROR);
|
|
905
|
-
}
|
|
906
|
-
else {
|
|
907
|
-
// Show help for usage errors (unknown arguments, etc.)
|
|
908
|
-
console.error(msg);
|
|
909
|
-
console.error();
|
|
910
|
-
yargs.showHelp();
|
|
911
|
-
process.exit(constants_js_1.ExitCodes.CONFIG_ERROR);
|
|
912
|
-
}
|
|
913
|
-
})
|
|
914
|
-
.parse();
|
|
41
|
+
const cliBuilder = (0, builder_js_1.createCli)(controller);
|
|
42
|
+
await cliBuilder.parseAsync(argv);
|
|
915
43
|
}
|
|
916
44
|
catch (error) {
|
|
45
|
+
// Handle bargs errors
|
|
46
|
+
if (error instanceof bargs_1.HelpError) {
|
|
47
|
+
// Help was requested or invalid args - message already printed
|
|
48
|
+
process.exit(constants_js_1.ExitCodes.CONFIG_ERROR);
|
|
49
|
+
}
|
|
50
|
+
if (error instanceof bargs_1.BargsError) {
|
|
51
|
+
console.error('Error:', error.message);
|
|
52
|
+
process.exit(constants_js_1.ExitCodes.CONFIG_ERROR);
|
|
53
|
+
}
|
|
54
|
+
// Handle bargs validation errors (thrown as plain Error, not BargsError)
|
|
55
|
+
if (error instanceof Error &&
|
|
56
|
+
(error.message.startsWith('Invalid value for --') ||
|
|
57
|
+
error.message.startsWith('Missing required'))) {
|
|
58
|
+
console.error('Error:', error.message);
|
|
59
|
+
process.exit(constants_js_1.ExitCodes.CONFIG_ERROR);
|
|
60
|
+
}
|
|
61
|
+
// Handle ModestBench errors
|
|
62
|
+
if ((0, index_js_1.isModestBenchError)(error)) {
|
|
63
|
+
console.error('Error:', error.message);
|
|
64
|
+
if (process.env.DEBUG) {
|
|
65
|
+
console.error(error.stack);
|
|
66
|
+
}
|
|
67
|
+
// Show help for file discovery errors
|
|
68
|
+
if (error.code === constants_js_1.ErrorCodes.FILE_DISCOVERY_FAILED) {
|
|
69
|
+
process.exit(constants_js_1.ExitCodes.DISCOVERY_ERROR);
|
|
70
|
+
}
|
|
71
|
+
process.exit(constants_js_1.ExitCodes.RUNTIME_ERROR);
|
|
72
|
+
}
|
|
73
|
+
// Unexpected error
|
|
917
74
|
console.error('Unexpected error:', error instanceof Error ? error.message : String(error));
|
|
918
75
|
if (process.env.DEBUG) {
|
|
919
76
|
console.error(error);
|
|
@@ -922,87 +79,6 @@ const main = async (argv, abortController) => {
|
|
|
922
79
|
}
|
|
923
80
|
};
|
|
924
81
|
exports.main = main;
|
|
925
|
-
/**
|
|
926
|
-
* Create CLI context with dependency injection
|
|
927
|
-
*/
|
|
928
|
-
const createCliContext = async (options, abortController, engineType = constants_js_1.DEFAULT_ENGINE) => {
|
|
929
|
-
try {
|
|
930
|
-
const dependencies = (0, bootstrap_js_1.bootstrap)();
|
|
931
|
-
// Select engine based on type
|
|
932
|
-
const engine = engineType === constants_js_1.Engines.ACCURATE
|
|
933
|
-
? new index_js_1.AccurateEngine(dependencies)
|
|
934
|
-
: new index_js_1.TinybenchEngine(dependencies);
|
|
935
|
-
// Register built-in reporters
|
|
936
|
-
engine.registerReporter(constants_js_1.Reporters.HUMAN, new index_js_3.HumanReporter({
|
|
937
|
-
color: !options.noColor,
|
|
938
|
-
verbose: options.verbose,
|
|
939
|
-
}));
|
|
940
|
-
engine.registerReporter('json', new index_js_3.JsonReporter({
|
|
941
|
-
prettyPrint: false,
|
|
942
|
-
}));
|
|
943
|
-
engine.registerReporter('csv', new index_js_3.CsvReporter({
|
|
944
|
-
includeHeaders: true,
|
|
945
|
-
includeMetadata: true,
|
|
946
|
-
}));
|
|
947
|
-
engine.registerReporter('simple', new index_js_3.SimpleReporter({
|
|
948
|
-
verbose: options.verbose,
|
|
949
|
-
}));
|
|
950
|
-
engine.registerReporter('nyan', new index_js_3.NyanReporter({
|
|
951
|
-
color: !options.noColor,
|
|
952
|
-
}));
|
|
953
|
-
return {
|
|
954
|
-
abortController,
|
|
955
|
-
configManager: engine.configManager,
|
|
956
|
-
engine,
|
|
957
|
-
historyStorage: engine.historyStorage,
|
|
958
|
-
options,
|
|
959
|
-
progressManager: engine.progressManager,
|
|
960
|
-
reporterRegistry: engine.reporterRegistry,
|
|
961
|
-
};
|
|
962
|
-
}
|
|
963
|
-
catch (error) {
|
|
964
|
-
console.error('Failed to initialize ModestBench:', error instanceof Error ? error.message : String(error));
|
|
965
|
-
process.exit(constants_js_1.ExitCodes.CONFIG_ERROR);
|
|
966
|
-
}
|
|
967
|
-
};
|
|
968
|
-
/**
|
|
969
|
-
* Handle process signals gracefully
|
|
970
|
-
*/
|
|
971
|
-
const setupSignalHandlers = (abortController) => {
|
|
972
|
-
let abortRequested = false;
|
|
973
|
-
const handleSignal = (signal) => {
|
|
974
|
-
if (abortRequested) {
|
|
975
|
-
// Second signal, force exit
|
|
976
|
-
console.log(`\nReceived ${signal} again, forcing exit...`);
|
|
977
|
-
process.exit(computeExitCode(signal));
|
|
978
|
-
}
|
|
979
|
-
console.log(`\nReceived ${signal}, aborting benchmarks...`);
|
|
980
|
-
abortRequested = true;
|
|
981
|
-
abortController.abort();
|
|
982
|
-
// Give a short grace period for cleanup, then exit
|
|
983
|
-
setTimeout(() => {
|
|
984
|
-
console.log('\nBenchmark aborted.');
|
|
985
|
-
process.exit(computeExitCode(signal));
|
|
986
|
-
}, constants_js_1.ABORT_TIMEOUT);
|
|
987
|
-
};
|
|
988
|
-
process
|
|
989
|
-
.once('SIGINT', handleSignal)
|
|
990
|
-
.once('SIGQUIT', handleSignal)
|
|
991
|
-
.once('SIGTERM', handleSignal)
|
|
992
|
-
.once('uncaughtException', (error) => {
|
|
993
|
-
// Wrap non-ModestBench errors with UnknownError
|
|
994
|
-
const wrappedError = (0, index_js_2.isModestBenchError)(error)
|
|
995
|
-
? error
|
|
996
|
-
: new index_js_2.UnknownError(error.message, { cause: error });
|
|
997
|
-
console.error(`${wrappedError}`);
|
|
998
|
-
process.exit(constants_js_1.ExitCodes.RUNTIME_ERROR);
|
|
999
|
-
})
|
|
1000
|
-
.once('unhandledRejection', (reason) => {
|
|
1001
|
-
const wrappedError = new index_js_2.UnknownError((0, base_js_1.isError)(reason) ? reason.message : String(reason), { cause: reason });
|
|
1002
|
-
console.error(`${wrappedError}`);
|
|
1003
|
-
process.exit(constants_js_1.ExitCodes.RUNTIME_ERROR);
|
|
1004
|
-
});
|
|
1005
|
-
};
|
|
1006
82
|
// Run CLI if this file is executed directly
|
|
1007
83
|
const scriptPath = (0, node_url_1.fileURLToPath)(require("url").pathToFileURL(__filename));
|
|
1008
84
|
const argPath = process.argv[1];
|
|
@@ -1020,13 +96,4 @@ catch {
|
|
|
1020
96
|
(0, exports.cli)();
|
|
1021
97
|
}
|
|
1022
98
|
}
|
|
1023
|
-
/**
|
|
1024
|
-
* Compute the exit code based on the signal
|
|
1025
|
-
*
|
|
1026
|
-
* @param signal - The signal that caused the exit
|
|
1027
|
-
* @returns The exit code
|
|
1028
|
-
*/
|
|
1029
|
-
const computeExitCode = (signal) => {
|
|
1030
|
-
return 128 + (signal === 'SIGINT' ? 2 : signal === 'SIGQUIT' ? 3 : 15);
|
|
1031
|
-
};
|
|
1032
99
|
//# sourceMappingURL=index.js.map
|