Skip to content

Commit e1cfcc6

Browse files
boneskullclaude
andcommitted
chore(cli): use camelCaseValues transform for cleaner property access
Apply bargs' camelCaseValues transform to all parsers with kebab-case options. This enables cleaner property access in command handlers: - values.noColor instead of values['no-color'] - values.outputFile instead of values['output-file'] - values.excludeTag instead of values['exclude-tag'] - etc. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 4ab7fe3 commit e1cfcc6

File tree

8 files changed

+155
-126
lines changed

8 files changed

+155
-126
lines changed

src/cli/builder.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ export const createCli = (abortController: AbortController) => {
8686
cwd: values.cwd,
8787
engine: values.engine,
8888
exclude: values.exclude,
89-
excludeTags: values['exclude-tag'],
89+
excludeTags: values.excludeTag,
9090
iterations: values.iterations,
9191
json: values.json,
92-
jsonPretty: values['json-pretty'],
93-
noColor: values['no-color'],
92+
jsonPretty: values.jsonPretty,
93+
noColor: values.noColor,
9494
outputDir: values.output,
95-
outputFile: values['output-file'],
95+
outputFile: values.outputFile,
9696
pattern,
9797
progress: values.progress,
9898
quiet: values.quiet,
@@ -193,9 +193,9 @@ export const createCli = (abortController: AbortController) => {
193193
const exitCode = await handleCleanCommand(context, {
194194
confirm: values.yes,
195195
cwd: values.cwd,
196-
maxAge: values['max-age'],
197-
maxRuns: values['max-runs'],
198-
maxSize: values['max-size'],
196+
maxAge: values.maxAge,
197+
maxRuns: values.maxRuns,
198+
maxSize: values.maxSize,
199199
quiet: values.quiet,
200200
verbose: values.verbose,
201201
});
@@ -241,7 +241,7 @@ export const createCli = (abortController: AbortController) => {
241241
default: values.default,
242242
name,
243243
quiet: Boolean(values.quiet),
244-
runId: values['run-id'],
244+
runId: values.runId,
245245
verbose: values.verbose,
246246
});
247247
process.exit(exitCode);
@@ -321,7 +321,7 @@ export const createCli = (abortController: AbortController) => {
321321
const [type] = positionals;
322322
const context = await createCliContext(values, abortController);
323323
const exitCode = await initCommand(context, {
324-
configType: values['config-type'],
324+
configType: values.configType,
325325
cwd: values.cwd,
326326
examples: values.examples,
327327
force: values.force,
@@ -343,13 +343,13 @@ export const createCli = (abortController: AbortController) => {
343343
const context = {} as CliContext;
344344

345345
const options: AnalyzeOptions = {
346-
color: !values['no-color'],
346+
color: !values.noColor,
347347
command,
348348
cwd: values.cwd || process.cwd(),
349-
filterFile: values['filter-file'],
350-
groupByFile: values['group-by-file'],
349+
filterFile: values.filterFile,
350+
groupByFile: values.groupByFile,
351351
input: values.input,
352-
minPercent: values['min-percent'],
352+
minPercent: values.minPercent,
353353
top: values.top,
354354
};
355355

@@ -372,7 +372,7 @@ export const createCli = (abortController: AbortController) => {
372372
framework,
373373
iterations: values.iterations,
374374
json: values.json,
375-
noColor: values['no-color'],
375+
noColor: values.noColor,
376376
pattern: files,
377377
quiet: values.quiet,
378378
verbose: values.verbose,

src/cli/context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export const createCliContext = async (
6464
engine.registerReporter(
6565
Reporters.HUMAN,
6666
new HumanReporter({
67-
color: !options['no-color'],
67+
color: !options.noColor,
6868
verbose: options.verbose,
6969
}),
7070
);
@@ -94,7 +94,7 @@ export const createCliContext = async (
9494
engine.registerReporter(
9595
'nyan',
9696
new NyanReporter({
97-
color: !options['no-color'],
97+
color: !options.noColor,
9898
}),
9999
);
100100

src/cli/parsers/analyze.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @packageDocumentation
88
*/
99

10-
import { map, merge, opt, pos } from '@boneskull/bargs';
10+
import { camelCaseValues, map, merge, opt, pos } from '@boneskull/bargs';
1111

1212
/**
1313
* Base parser for `analyze` command options and positionals
@@ -44,17 +44,18 @@ const analyzeParserBase = merge(
4444
);
4545

4646
/**
47-
* Parser for `analyze` command with validation
47+
* Parser for `analyze` command with validation and camelCase values
4848
*
49-
* Validates that either a command or --input is provided.
49+
* Validates that either a command or --input is provided. Uses camelCaseValues
50+
* transform for cleaner property access.
5051
*/
5152
export const analyzeParser = map(
52-
analyzeParserBase,
53-
({ positionals, values }) => {
53+
map(analyzeParserBase, ({ positionals, values }) => {
5454
const [command] = positionals;
5555
if (!command && !values.input) {
5656
throw new Error('Either [command] or --input must be provided');
5757
}
5858
return { positionals, values };
59-
},
59+
}),
60+
camelCaseValues,
6061
);

src/cli/parsers/baseline.ts

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,38 @@
77
* @packageDocumentation
88
*/
99

10-
import { merge, opt, pos } from '@boneskull/bargs';
10+
import { camelCaseValues, map, merge, opt, pos } from '@boneskull/bargs';
1111

1212
/**
1313
* Parser for `baseline set` command
14+
*
15+
* Uses camelCaseValues transform for cleaner property access.
1416
*/
15-
export const baselineSetParser = merge(
16-
opt.options({
17-
branch: opt.string({
18-
description: 'Git branch name',
19-
}),
20-
commit: opt.string({
21-
description: 'Git commit SHA (40 characters)',
22-
}),
23-
default: opt.boolean({
24-
description: 'Set as default baseline',
25-
}),
26-
'run-id': opt.string({
27-
description: 'Specific run ID to save (default: most recent)',
28-
}),
29-
}),
30-
pos.positionals(
31-
pos.string({
32-
description: 'Name for the baseline',
33-
name: 'name',
34-
required: true,
17+
export const baselineSetParser = map(
18+
merge(
19+
opt.options({
20+
branch: opt.string({
21+
description: 'Git branch name',
22+
}),
23+
commit: opt.string({
24+
description: 'Git commit SHA (40 characters)',
25+
}),
26+
default: opt.boolean({
27+
description: 'Set as default baseline',
28+
}),
29+
'run-id': opt.string({
30+
description: 'Specific run ID to save (default: most recent)',
31+
}),
3532
}),
33+
pos.positionals(
34+
pos.string({
35+
description: 'Name for the baseline',
36+
name: 'name',
37+
required: true,
38+
}),
39+
),
3640
),
41+
camelCaseValues,
3742
);
3843

3944
/**

src/cli/parsers/global.ts

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,39 @@
77
* @packageDocumentation
88
*/
99

10-
import { opt } from '@boneskull/bargs';
10+
import { camelCaseValues, map, opt } from '@boneskull/bargs';
1111

1212
/**
1313
* Global options available to all commands
14+
*
15+
* Uses camelCaseValues transform so handlers can use `values.noColor` instead
16+
* of `values['no-color']`.
1417
*/
15-
export const globalOptions = opt.options({
16-
config: opt.string({
17-
aliases: ['c'],
18-
description: 'Path to configuration file',
19-
}),
20-
cwd: opt.string({
21-
description: 'Working directory',
22-
}),
23-
json: opt.boolean({
24-
description: 'Output results in JSON format',
25-
}),
26-
'no-color': opt.boolean({
27-
description: 'Disable colored output',
18+
export const globalOptions = map(
19+
opt.options({
20+
config: opt.string({
21+
aliases: ['c'],
22+
description: 'Path to configuration file',
23+
}),
24+
cwd: opt.string({
25+
description: 'Working directory',
26+
}),
27+
json: opt.boolean({
28+
description: 'Output results in JSON format',
29+
}),
30+
'no-color': opt.boolean({
31+
description: 'Disable colored output',
32+
}),
33+
progress: opt.boolean({
34+
description: 'Show animated progress bar',
35+
}),
36+
verbose: opt.boolean({
37+
aliases: ['v'],
38+
description: 'Enable verbose output',
39+
}),
2840
}),
29-
progress: opt.boolean({
30-
description: 'Show animated progress bar',
31-
}),
32-
verbose: opt.boolean({
33-
aliases: ['v'],
34-
description: 'Enable verbose output',
35-
}),
36-
});
41+
camelCaseValues,
42+
);
3743

3844
/**
3945
* Additional global options for history and baseline subcommands

src/cli/parsers/history.ts

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @packageDocumentation
88
*/
99

10-
import { map, merge, opt, pos } from '@boneskull/bargs';
10+
import { camelCaseValues, map, merge, opt, pos } from '@boneskull/bargs';
1111

1212
/**
1313
* Parser for `history list` command
@@ -115,32 +115,36 @@ export const historyTrendsParser = merge(
115115
/**
116116
* Parser for `history clean` command
117117
*
118-
* Includes validation requiring at least one cleanup criterion.
118+
* Includes validation requiring at least one cleanup criterion. Uses
119+
* camelCaseValues transform for cleaner property access.
119120
*/
120121
export const historyCleanParser = map(
121-
opt.options({
122-
'max-age': opt.number({
123-
description: 'Remove runs older than this many days',
124-
}),
125-
'max-runs': opt.number({
126-
description: 'Keep only this many most recent runs',
127-
}),
128-
'max-size': opt.number({
129-
description: 'Keep history under this size in bytes',
130-
}),
131-
yes: opt.boolean({
132-
aliases: ['y'],
133-
description: 'Confirm cleanup without prompting',
134-
}),
135-
}),
136-
({ positionals, values }) => {
137-
if (!values['max-age'] && !values['max-runs'] && !values['max-size']) {
138-
throw new Error(
139-
'At least one cleanup criterion must be specified (--max-age, --max-runs, or --max-size)',
140-
);
141-
}
142-
return { positionals, values };
143-
},
122+
map(
123+
opt.options({
124+
'max-age': opt.number({
125+
description: 'Remove runs older than this many days',
126+
}),
127+
'max-runs': opt.number({
128+
description: 'Keep only this many most recent runs',
129+
}),
130+
'max-size': opt.number({
131+
description: 'Keep history under this size in bytes',
132+
}),
133+
yes: opt.boolean({
134+
aliases: ['y'],
135+
description: 'Confirm cleanup without prompting',
136+
}),
137+
}),
138+
({ positionals, values }) => {
139+
if (!values['max-age'] && !values['max-runs'] && !values['max-size']) {
140+
throw new Error(
141+
'At least one cleanup criterion must be specified (--max-age, --max-runs, or --max-size)',
142+
);
143+
}
144+
return { positionals, values };
145+
},
146+
),
147+
camelCaseValues,
144148
);
145149

146150
/**

src/cli/parsers/init.ts

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,40 @@
66
* @packageDocumentation
77
*/
88

9-
import { merge, opt, pos } from '@boneskull/bargs';
9+
import { camelCaseValues, map, merge, opt, pos } from '@boneskull/bargs';
1010

1111
/**
1212
* Parser for `init` command
13+
*
14+
* Uses camelCaseValues transform for cleaner property access.
1315
*/
14-
export const initParser = merge(
15-
opt.options({
16-
'config-type': opt.enum(['json', 'yaml', 'js', 'ts'] as const, {
17-
description: 'Configuration file format',
18-
}),
19-
examples: opt.boolean({
20-
description: 'Include example benchmark files',
21-
}),
22-
force: opt.boolean({
23-
description: 'Overwrite existing files',
24-
}),
25-
quiet: opt.boolean({
26-
aliases: ['q'],
27-
description: 'Minimal output',
28-
}),
29-
yes: opt.boolean({
30-
aliases: ['y'],
31-
description: 'Accept all prompts automatically',
32-
}),
33-
}),
34-
pos.positionals(
35-
pos.enum(['basic', 'advanced', 'library'] as const, {
36-
description: 'Type of project to initialize',
37-
name: 'type',
16+
export const initParser = map(
17+
merge(
18+
opt.options({
19+
'config-type': opt.enum(['json', 'yaml', 'js', 'ts'] as const, {
20+
description: 'Configuration file format',
21+
}),
22+
examples: opt.boolean({
23+
description: 'Include example benchmark files',
24+
}),
25+
force: opt.boolean({
26+
description: 'Overwrite existing files',
27+
}),
28+
quiet: opt.boolean({
29+
aliases: ['q'],
30+
description: 'Minimal output',
31+
}),
32+
yes: opt.boolean({
33+
aliases: ['y'],
34+
description: 'Accept all prompts automatically',
35+
}),
3836
}),
37+
pos.positionals(
38+
pos.enum(['basic', 'advanced', 'library'] as const, {
39+
description: 'Type of project to initialize',
40+
name: 'type',
41+
}),
42+
),
3943
),
44+
camelCaseValues,
4045
);

0 commit comments

Comments
 (0)