modestbench 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/LICENSE.md +55 -0
- package/README.md +699 -0
- package/dist/bootstrap.cjs +37 -0
- package/dist/bootstrap.cjs.map +1 -0
- package/dist/bootstrap.d.cts +17 -0
- package/dist/bootstrap.d.cts.map +1 -0
- package/dist/bootstrap.d.ts +17 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +33 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/cli/commands/history.cjs +459 -0
- package/dist/cli/commands/history.cjs.map +1 -0
- package/dist/cli/commands/history.d.cts +34 -0
- package/dist/cli/commands/history.d.cts.map +1 -0
- package/dist/cli/commands/history.d.ts +34 -0
- package/dist/cli/commands/history.d.ts.map +1 -0
- package/dist/cli/commands/history.js +422 -0
- package/dist/cli/commands/history.js.map +1 -0
- package/dist/cli/commands/init.cjs +566 -0
- package/dist/cli/commands/init.cjs.map +1 -0
- package/dist/cli/commands/init.d.cts +26 -0
- package/dist/cli/commands/init.d.cts.map +1 -0
- package/dist/cli/commands/init.d.ts +26 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +562 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/run.cjs +285 -0
- package/dist/cli/commands/run.cjs.map +1 -0
- package/dist/cli/commands/run.d.cts +37 -0
- package/dist/cli/commands/run.d.cts.map +1 -0
- package/dist/cli/commands/run.d.ts +37 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +248 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/index.cjs +523 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +58 -0
- package/dist/cli/index.d.cts.map +1 -0
- package/dist/cli/index.d.ts +58 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +515 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/manager.cjs +370 -0
- package/dist/config/manager.cjs.map +1 -0
- package/dist/config/manager.d.cts +46 -0
- package/dist/config/manager.d.cts.map +1 -0
- package/dist/config/manager.d.ts +46 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +333 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/schema.cjs +182 -0
- package/dist/config/schema.cjs.map +1 -0
- package/dist/config/schema.d.cts +51 -0
- package/dist/config/schema.d.cts.map +1 -0
- package/dist/config/schema.d.ts +51 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +145 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/constants.cjs +22 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.d.cts +10 -0
- package/dist/constants.d.cts.map +1 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +19 -0
- package/dist/constants.js.map +1 -0
- package/dist/core/benchmark-schema.cjs +135 -0
- package/dist/core/benchmark-schema.cjs.map +1 -0
- package/dist/core/benchmark-schema.d.cts +139 -0
- package/dist/core/benchmark-schema.d.cts.map +1 -0
- package/dist/core/benchmark-schema.d.ts +139 -0
- package/dist/core/benchmark-schema.d.ts.map +1 -0
- package/dist/core/benchmark-schema.js +132 -0
- package/dist/core/benchmark-schema.js.map +1 -0
- package/dist/core/engine.cjs +669 -0
- package/dist/core/engine.cjs.map +1 -0
- package/dist/core/engine.d.cts +128 -0
- package/dist/core/engine.d.cts.map +1 -0
- package/dist/core/engine.d.ts +128 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +632 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/engines/accurate-engine.cjs +292 -0
- package/dist/core/engines/accurate-engine.cjs.map +1 -0
- package/dist/core/engines/accurate-engine.d.cts +63 -0
- package/dist/core/engines/accurate-engine.d.cts.map +1 -0
- package/dist/core/engines/accurate-engine.d.ts +63 -0
- package/dist/core/engines/accurate-engine.d.ts.map +1 -0
- package/dist/core/engines/accurate-engine.js +288 -0
- package/dist/core/engines/accurate-engine.js.map +1 -0
- package/dist/core/engines/index.cjs +21 -0
- package/dist/core/engines/index.cjs.map +1 -0
- package/dist/core/engines/index.d.cts +16 -0
- package/dist/core/engines/index.d.cts.map +1 -0
- package/dist/core/engines/index.d.ts +16 -0
- package/dist/core/engines/index.d.ts.map +1 -0
- package/dist/core/engines/index.js +16 -0
- package/dist/core/engines/index.js.map +1 -0
- package/dist/core/engines/tinybench-engine.cjs +286 -0
- package/dist/core/engines/tinybench-engine.cjs.map +1 -0
- package/dist/core/engines/tinybench-engine.d.cts +18 -0
- package/dist/core/engines/tinybench-engine.d.cts.map +1 -0
- package/dist/core/engines/tinybench-engine.d.ts +18 -0
- package/dist/core/engines/tinybench-engine.d.ts.map +1 -0
- package/dist/core/engines/tinybench-engine.js +282 -0
- package/dist/core/engines/tinybench-engine.js.map +1 -0
- package/dist/core/error-manager.cjs +303 -0
- package/dist/core/error-manager.cjs.map +1 -0
- package/dist/core/error-manager.d.cts +77 -0
- package/dist/core/error-manager.d.cts.map +1 -0
- package/dist/core/error-manager.d.ts +77 -0
- package/dist/core/error-manager.d.ts.map +1 -0
- package/dist/core/error-manager.js +299 -0
- package/dist/core/error-manager.js.map +1 -0
- package/dist/core/loader.cjs +287 -0
- package/dist/core/loader.cjs.map +1 -0
- package/dist/core/loader.d.cts +55 -0
- package/dist/core/loader.d.cts.map +1 -0
- package/dist/core/loader.d.ts +55 -0
- package/dist/core/loader.d.ts.map +1 -0
- package/dist/core/loader.js +250 -0
- package/dist/core/loader.js.map +1 -0
- package/dist/core/stats-utils.cjs +99 -0
- package/dist/core/stats-utils.cjs.map +1 -0
- package/dist/core/stats-utils.d.cts +50 -0
- package/dist/core/stats-utils.d.cts.map +1 -0
- package/dist/core/stats-utils.d.ts +50 -0
- package/dist/core/stats-utils.d.ts.map +1 -0
- package/dist/core/stats-utils.js +94 -0
- package/dist/core/stats-utils.js.map +1 -0
- package/dist/index.cjs +64 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +22 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/progress/manager.cjs +325 -0
- package/dist/progress/manager.cjs.map +1 -0
- package/dist/progress/manager.d.cts +125 -0
- package/dist/progress/manager.d.cts.map +1 -0
- package/dist/progress/manager.d.ts +125 -0
- package/dist/progress/manager.d.ts.map +1 -0
- package/dist/progress/manager.js +321 -0
- package/dist/progress/manager.js.map +1 -0
- package/dist/reporters/csv.cjs +250 -0
- package/dist/reporters/csv.cjs.map +1 -0
- package/dist/reporters/csv.d.cts +92 -0
- package/dist/reporters/csv.d.cts.map +1 -0
- package/dist/reporters/csv.d.ts +92 -0
- package/dist/reporters/csv.d.ts.map +1 -0
- package/dist/reporters/csv.js +246 -0
- package/dist/reporters/csv.js.map +1 -0
- package/dist/reporters/human.cjs +516 -0
- package/dist/reporters/human.cjs.map +1 -0
- package/dist/reporters/human.d.cts +86 -0
- package/dist/reporters/human.d.cts.map +1 -0
- package/dist/reporters/human.d.ts +86 -0
- package/dist/reporters/human.d.ts.map +1 -0
- package/dist/reporters/human.js +509 -0
- package/dist/reporters/human.js.map +1 -0
- package/dist/reporters/index.cjs +17 -0
- package/dist/reporters/index.cjs.map +1 -0
- package/dist/reporters/index.d.cts +10 -0
- package/dist/reporters/index.d.cts.map +1 -0
- package/dist/reporters/index.d.ts +10 -0
- package/dist/reporters/index.d.ts.map +1 -0
- package/dist/reporters/index.js +10 -0
- package/dist/reporters/index.js.map +1 -0
- package/dist/reporters/json.cjs +215 -0
- package/dist/reporters/json.cjs.map +1 -0
- package/dist/reporters/json.d.cts +79 -0
- package/dist/reporters/json.d.cts.map +1 -0
- package/dist/reporters/json.d.ts +79 -0
- package/dist/reporters/json.d.ts.map +1 -0
- package/dist/reporters/json.js +211 -0
- package/dist/reporters/json.js.map +1 -0
- package/dist/reporters/registry.cjs +255 -0
- package/dist/reporters/registry.cjs.map +1 -0
- package/dist/reporters/registry.d.cts +155 -0
- package/dist/reporters/registry.d.cts.map +1 -0
- package/dist/reporters/registry.d.ts +155 -0
- package/dist/reporters/registry.d.ts.map +1 -0
- package/dist/reporters/registry.js +249 -0
- package/dist/reporters/registry.js.map +1 -0
- package/dist/reporters/simple.cjs +328 -0
- package/dist/reporters/simple.cjs.map +1 -0
- package/dist/reporters/simple.d.cts +51 -0
- package/dist/reporters/simple.d.cts.map +1 -0
- package/dist/reporters/simple.d.ts +51 -0
- package/dist/reporters/simple.d.ts.map +1 -0
- package/dist/reporters/simple.js +321 -0
- package/dist/reporters/simple.js.map +1 -0
- package/dist/schema/modestbench-config.schema.json +162 -0
- package/dist/storage/history.cjs +456 -0
- package/dist/storage/history.cjs.map +1 -0
- package/dist/storage/history.d.cts +99 -0
- package/dist/storage/history.d.cts.map +1 -0
- package/dist/storage/history.d.ts +99 -0
- package/dist/storage/history.d.ts.map +1 -0
- package/dist/storage/history.js +452 -0
- package/dist/storage/history.js.map +1 -0
- package/dist/types/cli.cjs +21 -0
- package/dist/types/cli.cjs.map +1 -0
- package/dist/types/cli.d.cts +296 -0
- package/dist/types/cli.d.cts.map +1 -0
- package/dist/types/cli.d.ts +296 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/cli.js +18 -0
- package/dist/types/cli.js.map +1 -0
- package/dist/types/core.cjs +14 -0
- package/dist/types/core.cjs.map +1 -0
- package/dist/types/core.d.cts +380 -0
- package/dist/types/core.d.cts.map +1 -0
- package/dist/types/core.d.ts +380 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/core.js +13 -0
- package/dist/types/core.js.map +1 -0
- package/dist/types/index.cjs +27 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +11 -0
- package/dist/types/index.d.cts.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/interfaces.cjs +10 -0
- package/dist/types/interfaces.cjs.map +1 -0
- package/dist/types/interfaces.d.cts +381 -0
- package/dist/types/interfaces.d.cts.map +1 -0
- package/dist/types/interfaces.d.ts +381 -0
- package/dist/types/interfaces.d.ts.map +1 -0
- package/dist/types/interfaces.js +9 -0
- package/dist/types/interfaces.js.map +1 -0
- package/dist/types/utility.cjs +92 -0
- package/dist/types/utility.cjs.map +1 -0
- package/dist/types/utility.d.cts +330 -0
- package/dist/types/utility.d.cts.map +1 -0
- package/dist/types/utility.d.ts +330 -0
- package/dist/types/utility.d.ts.map +1 -0
- package/dist/types/utility.js +78 -0
- package/dist/types/utility.js.map +1 -0
- package/package.json +211 -0
- package/src/bootstrap.ts +35 -0
- package/src/cli/commands/history.ts +569 -0
- package/src/cli/commands/init.ts +658 -0
- package/src/cli/commands/run.ts +346 -0
- package/src/cli/index.ts +642 -0
- package/src/config/manager.ts +387 -0
- package/src/config/schema.ts +188 -0
- package/src/constants.ts +21 -0
- package/src/core/benchmark-schema.ts +185 -0
- package/src/core/engine.ts +888 -0
- package/src/core/engines/accurate-engine.ts +408 -0
- package/src/core/engines/index.ts +16 -0
- package/src/core/engines/tinybench-engine.ts +335 -0
- package/src/core/error-manager.ts +372 -0
- package/src/core/loader.ts +324 -0
- package/src/core/stats-utils.ts +135 -0
- package/src/index.ts +46 -0
- package/src/progress/manager.ts +415 -0
- package/src/reporters/csv.ts +368 -0
- package/src/reporters/human.ts +707 -0
- package/src/reporters/index.ts +10 -0
- package/src/reporters/json.ts +302 -0
- package/src/reporters/registry.ts +349 -0
- package/src/reporters/simple.ts +459 -0
- package/src/storage/history.ts +600 -0
- package/src/types/cli.ts +312 -0
- package/src/types/core.ts +414 -0
- package/src/types/index.ts +18 -0
- package/src/types/interfaces.ts +451 -0
- package/src/types/utility.ts +446 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModestBench Run Command
|
|
3
|
+
*
|
|
4
|
+
* Execute benchmark files with configuration and reporting. Main entry point
|
|
5
|
+
* for running benchmarks with real-time progress.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { resolve } from 'node:path';
|
|
9
|
+
|
|
10
|
+
import type { BenchmarkRun } from '../../types/index.js';
|
|
11
|
+
import type { CliContext } from '../index.js';
|
|
12
|
+
|
|
13
|
+
import { ExitCodes } from '../../types/cli.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Run command options interface
|
|
17
|
+
*/
|
|
18
|
+
interface RunOptions {
|
|
19
|
+
bail?: boolean | undefined;
|
|
20
|
+
config?: string | undefined;
|
|
21
|
+
cwd: string;
|
|
22
|
+
engine?: 'accurate' | 'tinybench' | undefined;
|
|
23
|
+
exclude?: string[] | undefined;
|
|
24
|
+
excludeTags?: string[] | undefined;
|
|
25
|
+
iterations?: number | undefined;
|
|
26
|
+
json?: boolean | undefined;
|
|
27
|
+
noColor?: boolean | undefined;
|
|
28
|
+
outputDir?: string | undefined;
|
|
29
|
+
pattern: string[];
|
|
30
|
+
progress?: boolean | undefined;
|
|
31
|
+
quiet?: boolean | undefined;
|
|
32
|
+
reporters: string[];
|
|
33
|
+
tags?: string[] | undefined;
|
|
34
|
+
time?: number | undefined;
|
|
35
|
+
timeout?: number | undefined;
|
|
36
|
+
verbose?: boolean | undefined;
|
|
37
|
+
warmup?: number | undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Handle run command
|
|
42
|
+
*/
|
|
43
|
+
export const handleRunCommand = async (
|
|
44
|
+
context: CliContext,
|
|
45
|
+
options: RunOptions,
|
|
46
|
+
): Promise<number> => {
|
|
47
|
+
// Check if JSON reporter is being used (need quiet output for clean JSON)
|
|
48
|
+
// Only force quiet mode if json is used AND no output directory is specified
|
|
49
|
+
// (i.e., outputting to stdout where we need clean JSON)
|
|
50
|
+
const isUsingJsonReporter = options.reporters?.includes('json') ?? false;
|
|
51
|
+
const shouldBeQuiet =
|
|
52
|
+
options.quiet || (isUsingJsonReporter && !options.outputDir);
|
|
53
|
+
const verbose = options.verbose ?? false;
|
|
54
|
+
// CLI messages on stderr should only be suppressed by explicit --quiet, not JSON-forced quiet
|
|
55
|
+
const showCliMessages = verbose && !options.quiet;
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
// Step 1: Load and merge configuration
|
|
59
|
+
if (showCliMessages) {
|
|
60
|
+
console.error('Loading configuration...');
|
|
61
|
+
}
|
|
62
|
+
const config = await loadConfiguration(context, options);
|
|
63
|
+
|
|
64
|
+
// Step 2: Configure reporters
|
|
65
|
+
if (showCliMessages) {
|
|
66
|
+
console.error('Setting up reporters...');
|
|
67
|
+
}
|
|
68
|
+
const reporters = await setupReporters(
|
|
69
|
+
context,
|
|
70
|
+
config,
|
|
71
|
+
shouldBeQuiet,
|
|
72
|
+
verbose,
|
|
73
|
+
showCliMessages,
|
|
74
|
+
options.quiet ?? false,
|
|
75
|
+
options.outputDir,
|
|
76
|
+
options.progress,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// Step 3: Discovery phase
|
|
80
|
+
if (showCliMessages) {
|
|
81
|
+
console.error('Discovering benchmark files...');
|
|
82
|
+
}
|
|
83
|
+
const discoveredFiles = await context.engine.discover(
|
|
84
|
+
config.pattern,
|
|
85
|
+
config.exclude,
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
if (showCliMessages) {
|
|
89
|
+
console.error(`Found ${discoveredFiles.length} benchmark file(s)`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Step 4: Validation phase
|
|
93
|
+
if (showCliMessages) {
|
|
94
|
+
console.error('Validating benchmark files...');
|
|
95
|
+
}
|
|
96
|
+
const validationResult = await context.engine.validate(discoveredFiles);
|
|
97
|
+
|
|
98
|
+
if (validationResult.warnings.length > 0) {
|
|
99
|
+
if (showCliMessages) {
|
|
100
|
+
console.error('Validation warnings:');
|
|
101
|
+
for (const warning of validationResult.warnings) {
|
|
102
|
+
console.error(` ${warning.code}: ${warning.message}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!validationResult.valid) {
|
|
108
|
+
if (!shouldBeQuiet) {
|
|
109
|
+
console.error('Validation errors:');
|
|
110
|
+
for (const error of validationResult.errors) {
|
|
111
|
+
console.error(` ${error.code}: ${error.message}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return ExitCodes.ValidationError;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Step 5: Execution phase
|
|
118
|
+
if (showCliMessages) {
|
|
119
|
+
console.error('Starting benchmark execution...');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const runConfig = {
|
|
123
|
+
...config,
|
|
124
|
+
cwd: options.cwd,
|
|
125
|
+
files: discoveredFiles,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const executionResult = await context.engine.execute(
|
|
129
|
+
runConfig,
|
|
130
|
+
reporters,
|
|
131
|
+
context.abortController.signal,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Step 6: Results handling
|
|
135
|
+
// Check if aborted by signal
|
|
136
|
+
if (context.abortController.signal.aborted) {
|
|
137
|
+
if (!shouldBeQuiet) {
|
|
138
|
+
console.error('\n✋ Benchmark run aborted by user');
|
|
139
|
+
}
|
|
140
|
+
// Exit with SIGINT code (128 + 2 = 130)
|
|
141
|
+
process.exit(130);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return handleResults(executionResult, options, shouldBeQuiet);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
if (!shouldBeQuiet) {
|
|
147
|
+
console.error(
|
|
148
|
+
`Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Return appropriate exit code based on error type
|
|
153
|
+
if (error instanceof Error) {
|
|
154
|
+
if (
|
|
155
|
+
error.message.includes('Configuration error') ||
|
|
156
|
+
error.message.includes('Config file not found') ||
|
|
157
|
+
error.message.includes('Failed to load config')
|
|
158
|
+
) {
|
|
159
|
+
return ExitCodes.ConfigurationError;
|
|
160
|
+
}
|
|
161
|
+
if (
|
|
162
|
+
error.message.includes('No files found') ||
|
|
163
|
+
error.message.includes('No benchmark files found') ||
|
|
164
|
+
error.message.includes('File discovery')
|
|
165
|
+
) {
|
|
166
|
+
return ExitCodes.FileDiscoveryError;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return ExitCodes.GeneralError;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Handle execution results and determine appropriate exit code
|
|
176
|
+
*/
|
|
177
|
+
const handleResults = (
|
|
178
|
+
executionResult: BenchmarkRun,
|
|
179
|
+
_options: RunOptions,
|
|
180
|
+
_shouldBeQuiet: boolean,
|
|
181
|
+
): number => {
|
|
182
|
+
// The reporters should handle displaying results
|
|
183
|
+
// This function only determines the exit code
|
|
184
|
+
|
|
185
|
+
// Check if any files failed to load/execute
|
|
186
|
+
const hasFileErrors = executionResult.files.some((file) => file.error);
|
|
187
|
+
|
|
188
|
+
// Determine exit code based on results
|
|
189
|
+
if (executionResult && executionResult.summary) {
|
|
190
|
+
// Return error if there are failed tasks OR file-level errors
|
|
191
|
+
return executionResult.summary.failedTasks > 0 || hasFileErrors
|
|
192
|
+
? ExitCodes.GeneralError
|
|
193
|
+
: ExitCodes.Success;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return ExitCodes.Success;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Load and merge configuration from various sources
|
|
201
|
+
*/
|
|
202
|
+
const loadConfiguration = async (context: CliContext, options: RunOptions) => {
|
|
203
|
+
try {
|
|
204
|
+
// Create CLI arguments object for configuration merger
|
|
205
|
+
const cliArgs: Record<string, unknown> = {};
|
|
206
|
+
|
|
207
|
+
// Map CLI arguments to config properties
|
|
208
|
+
// Pass pattern as-is, even if empty (loader will provide defaults)
|
|
209
|
+
if (options.pattern !== undefined) {
|
|
210
|
+
// If pattern is provided, use it; if empty array, pass it (for defaults)
|
|
211
|
+
cliArgs.pattern =
|
|
212
|
+
options.pattern.length === 1 ? options.pattern[0] : options.pattern;
|
|
213
|
+
}
|
|
214
|
+
if (options.reporters) {
|
|
215
|
+
cliArgs.reporters = options.reporters;
|
|
216
|
+
}
|
|
217
|
+
if (options.outputDir) {
|
|
218
|
+
cliArgs.outputDir = resolve(options.cwd, options.outputDir);
|
|
219
|
+
}
|
|
220
|
+
if (options.iterations) {
|
|
221
|
+
cliArgs.iterations = options.iterations;
|
|
222
|
+
}
|
|
223
|
+
if (options.time) {
|
|
224
|
+
cliArgs.time = options.time;
|
|
225
|
+
}
|
|
226
|
+
if (options.warmup !== undefined) {
|
|
227
|
+
cliArgs.warmup = options.warmup;
|
|
228
|
+
}
|
|
229
|
+
if (options.bail !== undefined) {
|
|
230
|
+
cliArgs.bail = options.bail;
|
|
231
|
+
}
|
|
232
|
+
if (options.exclude) {
|
|
233
|
+
cliArgs.exclude = options.exclude;
|
|
234
|
+
}
|
|
235
|
+
if (options.timeout) {
|
|
236
|
+
cliArgs.timeout = options.timeout;
|
|
237
|
+
}
|
|
238
|
+
if (options.quiet !== undefined) {
|
|
239
|
+
cliArgs.quiet = options.quiet;
|
|
240
|
+
}
|
|
241
|
+
if (options.verbose !== undefined) {
|
|
242
|
+
cliArgs.verbose = options.verbose;
|
|
243
|
+
}
|
|
244
|
+
if (options.tags) {
|
|
245
|
+
cliArgs.tags = options.tags;
|
|
246
|
+
}
|
|
247
|
+
if (options.excludeTags) {
|
|
248
|
+
cliArgs.excludeTags = options.excludeTags;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Load configuration with CLI argument precedence
|
|
252
|
+
const config = await context.configManager.load(options.config, cliArgs);
|
|
253
|
+
|
|
254
|
+
return config;
|
|
255
|
+
} catch (error) {
|
|
256
|
+
throw new Error(
|
|
257
|
+
`Configuration error: ${error instanceof Error ? error.message : String(error)}`,
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Setup and configure reporters based on configuration
|
|
264
|
+
*/
|
|
265
|
+
const setupReporters = async (
|
|
266
|
+
context: CliContext,
|
|
267
|
+
config: { outputDir?: string; reporters?: string[] },
|
|
268
|
+
shouldBeQuiet: boolean,
|
|
269
|
+
isVerbose: boolean,
|
|
270
|
+
showCliMessages: boolean,
|
|
271
|
+
explicitQuiet: boolean,
|
|
272
|
+
explicitOutputDir?: string,
|
|
273
|
+
progressOption?: boolean,
|
|
274
|
+
) => {
|
|
275
|
+
try {
|
|
276
|
+
const reporters = [];
|
|
277
|
+
const requestedReporters = config.reporters || ['human'];
|
|
278
|
+
|
|
279
|
+
// Dynamically import reporters for proper configuration
|
|
280
|
+
const { HumanReporter } = await import('../../reporters/human.js');
|
|
281
|
+
const { JsonReporter } = await import('../../reporters/json.js');
|
|
282
|
+
const { CsvReporter } = await import('../../reporters/csv.js');
|
|
283
|
+
const { SimpleReporter } = await import('../../reporters/simple.js');
|
|
284
|
+
|
|
285
|
+
// Only use file output if --output was explicitly provided
|
|
286
|
+
// Use the explicit output dir if provided, otherwise check config
|
|
287
|
+
const outputDir = explicitOutputDir
|
|
288
|
+
? resolve(explicitOutputDir)
|
|
289
|
+
: undefined;
|
|
290
|
+
|
|
291
|
+
for (const reporterName of requestedReporters) {
|
|
292
|
+
let reporter;
|
|
293
|
+
|
|
294
|
+
// Create reporter instances with output path configuration
|
|
295
|
+
if (reporterName === 'human') {
|
|
296
|
+
reporter = new HumanReporter({
|
|
297
|
+
color: true,
|
|
298
|
+
progress: progressOption ?? true,
|
|
299
|
+
quiet: explicitQuiet, // Only applies explicit --quiet flag; JSON reporter forcing quiet mode does not affect HumanReporter progress output
|
|
300
|
+
verbose: isVerbose,
|
|
301
|
+
});
|
|
302
|
+
} else if (reporterName === 'json') {
|
|
303
|
+
reporter = new JsonReporter({
|
|
304
|
+
...(outputDir ? { outputPath: `${outputDir}/results.json` } : {}),
|
|
305
|
+
prettyPrint: true,
|
|
306
|
+
quiet: shouldBeQuiet, // JSON uses shouldBeQuiet to avoid polluting stdout
|
|
307
|
+
verbose: isVerbose,
|
|
308
|
+
});
|
|
309
|
+
} else if (reporterName === 'csv') {
|
|
310
|
+
reporter = new CsvReporter({
|
|
311
|
+
includeHeaders: true,
|
|
312
|
+
includeMetadata: true,
|
|
313
|
+
...(outputDir ? { outputPath: `${outputDir}/results.csv` } : {}),
|
|
314
|
+
quiet: explicitQuiet, // Only applies explicit --quiet flag; CSV output can coexist with progress messages on different streams
|
|
315
|
+
verbose: isVerbose,
|
|
316
|
+
});
|
|
317
|
+
} else if (reporterName === 'simple') {
|
|
318
|
+
reporter = new SimpleReporter({
|
|
319
|
+
quiet: explicitQuiet,
|
|
320
|
+
verbose: isVerbose,
|
|
321
|
+
});
|
|
322
|
+
} else {
|
|
323
|
+
// Fall back to registry for custom reporters
|
|
324
|
+
reporter = context.reporterRegistry.get(reporterName);
|
|
325
|
+
if (!reporter) {
|
|
326
|
+
const availableReporters = ['human', 'json', 'csv', 'simple'];
|
|
327
|
+
throw new Error(
|
|
328
|
+
`Unknown reporter: ${reporterName}. Available: ${availableReporters.join(', ')}`,
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
reporters.push(reporter);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (outputDir && showCliMessages) {
|
|
337
|
+
console.error(`Output directory configured: ${outputDir}`);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return reporters;
|
|
341
|
+
} catch (error) {
|
|
342
|
+
throw new Error(
|
|
343
|
+
`Reporter setup error: ${error instanceof Error ? error.message : String(error)}`,
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
};
|