Skip to content

Commit b7c8b77

Browse files
committed
fix(args): honor explicit value on boolean flags (--flag=false)
parseFlags set a boolean flag to `true` as soon as it matched the flag, before inspecting an inline `=value`. So `--flag=false` (or `--flag=0`) was silently set to `true` -- the opposite of what the user typed -- and the value was discarded. Honor an explicit value: `--flag=false`/`0`/`no`/`off` -> false; a bare `--flag` and `--flag=true` (or any other value) stay true, so there is no behavior change for existing usage. Adds parseFlags tests for the bare-flag and explicit-value cases.
1 parent 5f13ef5 commit b7c8b77

2 files changed

Lines changed: 18 additions & 1 deletion

File tree

src/args.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,12 @@ export function parseFlags(argv: string[], options: OptionDef[]): GlobalFlags {
114114
const camelKey = kebabToCamel(key);
115115

116116
if (schema.booleans.has(camelKey)) {
117-
(flags as Record<string, unknown>)[camelKey] = true;
117+
// A bare boolean flag (`--flag`) is true. Honour an explicit value
118+
// such as `--flag=false` / `--flag=0` instead of silently forcing the
119+
// flag to true and discarding what the user typed.
120+
(flags as Record<string, unknown>)[camelKey] =
121+
value === undefined ||
122+
!['false', '0', 'no', 'off'].includes(value.trim().toLowerCase());
118123
i++;
119124
continue;
120125
}

test/args.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { OptionDef } from '../src/command';
55
const OPTIONS: OptionDef[] = [
66
{ flag: '--timeout <seconds>', description: 'Request timeout', type: 'number' },
77
{ flag: '--message <text>', description: 'Message text', type: 'array' },
8+
{ flag: '--verbose', description: 'Verbose output' },
89
];
910

1011
describe('parseFlags', () => {
@@ -25,4 +26,15 @@ describe('parseFlags', () => {
2526

2627
expect(flags.timeout).toBe(1.5);
2728
});
29+
30+
it('treats a bare boolean flag as true', () => {
31+
expect(parseFlags(['--verbose'], OPTIONS).verbose).toBe(true);
32+
});
33+
34+
it('honours an explicit value on a boolean flag instead of forcing true', () => {
35+
// Regression: `--flag=false` / `--flag=0` were silently set to true.
36+
expect(parseFlags(['--verbose=false'], OPTIONS).verbose).toBe(false);
37+
expect(parseFlags(['--verbose=0'], OPTIONS).verbose).toBe(false);
38+
expect(parseFlags(['--verbose=true'], OPTIONS).verbose).toBe(true);
39+
});
2840
});

0 commit comments

Comments
 (0)