Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,12 @@ export function parseFlags(argv: string[], options: OptionDef[]): GlobalFlags {
const camelKey = kebabToCamel(key);

if (schema.booleans.has(camelKey)) {
(flags as Record<string, unknown>)[camelKey] = true;
// A bare boolean flag (`--flag`) is true. Honour an explicit value
// such as `--flag=false` / `--flag=0` instead of silently forcing the
// flag to true and discarding what the user typed.
(flags as Record<string, unknown>)[camelKey] =
value === undefined ||
!['false', '0', 'no', 'off'].includes(value.trim().toLowerCase());
i++;
continue;
}
Expand Down
12 changes: 12 additions & 0 deletions test/args.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { OptionDef } from '../src/command';
const OPTIONS: OptionDef[] = [
{ flag: '--timeout <seconds>', description: 'Request timeout', type: 'number' },
{ flag: '--message <text>', description: 'Message text', type: 'array' },
{ flag: '--verbose', description: 'Verbose output' },
];

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

expect(flags.timeout).toBe(1.5);
});

it('treats a bare boolean flag as true', () => {
expect(parseFlags(['--verbose'], OPTIONS).verbose).toBe(true);
});

it('honours an explicit value on a boolean flag instead of forcing true', () => {
// Regression: `--flag=false` / `--flag=0` were silently set to true.
expect(parseFlags(['--verbose=false'], OPTIONS).verbose).toBe(false);
expect(parseFlags(['--verbose=0'], OPTIONS).verbose).toBe(false);
expect(parseFlags(['--verbose=true'], OPTIONS).verbose).toBe(true);
});
});