Skip to content

Boolean arguments read via environment variables do not support no-prefixed variants #2501

@rtpg

Description

@rtpg

Given the following script:

#!/usr/bin/env node
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
const argv = yargs(
  hideBin(process.argv)
).env(
 "MY_CMD"
).option(
 'doThing',
 {type: 'boolean', default: true}
).parse()

console.log(`DO THING? ${argv.doThing}`);

My expectation would be that MY_CMD_DO_THING's environment variable would map to booleans in "the right way". I'd also expect for MY_CMD_NO_DO_THING to map to --no-do-thing's behavior.

Instead I've experienced the following:

+ bun run ./main.js
DO THING? true // expected: default is true
+ MY_CMD_DO_THING=1
+ bun run ./main.js
DO THING? false // unexpected: expected true by "1" being "truth"-y
+ MY_CMD_DO_THING=0
+ bun run ./main.js
DO THING? false // expected: expected false by "0" being "false"-y
+ MY_CMD_DO_THING=true
+ bun run ./main.js
DO THING? true // seems fine
+ MY_CMD_DO_THING=false
+ bun run ./main.js
DO THING? false // seems fine
+ MY_CMD_NO_DO_THING=1
+ bun run ./main.js
DO THING? true  // unexpected: expected false by no-do-thing + 1 being "truth"-y
+ MY_CMD_NO_DO_THING=0
+ bun run ./main.js
DO THING? true // guess this is right
+ MY_CMD_NO_DO_THING=true
+ bun run ./main.js
DO THING? true. // unexpected: expected false by no-do-thing + true being truthy
+ MY_CMD_NO_DO_THING=false
+ bun run ./main.js
DO THING? true

I think NO_DO_THING is just not looked at in its entirety, which isn't the end of the world, but seems to lack some notion of parity with the rest of the negation behavior.

But for CLI applications, having 1 or 0 represent true or false feels like something that makes sense. Here 1 turning into a false-y result is very surprising to me.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions