Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add .env method to Option for consulting environment variable for option value #1587

Merged
merged 19 commits into from Aug 24, 2021

Conversation

shadowspawn
Copy link
Collaborator

@shadowspawn shadowspawn commented Aug 19, 2021

Pull Request

Problem

Commander does not have any direct support for getting values from environment variables. You can pass them in as default, but this masks the default in the help and documentation is up to the user.

One of the reasons for improving "default" support was people using it to inject environment variable values, since there was not a more explicit way.

Related: #682 #928 #1266

Solution

Add .env(envvar) on Option. This is displayed in the help, like the default value.

Some implementation decisions:

  • env processed during parse (rather than when option added)
  • priority is default < env < cli
  • env processed after cli, and env not consulted if option was specified on cli
  • custom processing function is called if defined
  • not supporting pure environment variable without option flags
  • boolean flag just looks for environment variable defined, and does not consider value of environment variable

Example with option taking a value:

program.addOption(new Option('-p, --port <number>',  'specify port number')
  .env('PORT')
  .default(80)
);
program.parse();
console.log(program.opts());
% node env.js
{ port: '80' }

% PORT=999 node env.js    
{ port: '999' }

% PORT=999 node env.js -p 123
{ port: '123' }

% node env.js -h
Usage: env [options]

Options:
  -p, --port <number>  specify port number (default: 80, env: PORT)
  -h, --help           display help for command

Example with boolean option:

program.addOption(new Option('-c, --colour', 'turn on colour output').env('COLOUR'));
program.addOption(new Option('-C, --no-colour', 'turn off colour output').env('NO_COLOUR'));
program.parse();
console.log(program.opts());
% node env.js --help
Usage: env [options]

Options:
  -c, --colour     turn on colour output (env: COLOUR)
  -C, --no-colour  turn off colour output (env: NO_COLOUR)
  -h, --help       display help for command

% node env.js       
{}

% COLOUR= node env.js 
{ colour: true }

% COLOUR= node env.js --no-colour 
{ colour: false } 

% NO_COLOUR= node env.js         
{ colour: false }

% NO_COLOUR= node env.js --colour
{ colour: true }

Example with choices:

program.addOption(new Option('-s, --size <type>', 'specify size of drink').choices(['small', 'medium', 'large']).env('SIZE'));
% node env.js -h           
Usage: env [options]

Options:
  -s, --size <type>  specify size of drink (choices: "small", "medium", "large", env: SIZE)
  -h, --help         display help for command

% SIZE=small node env.js   
{ size: 'small' }

% SIZE=enormous node env.js 
error: option '-s, --size <type>' value 'enormous' from env 'SIZE' is invalid. Allowed choices are small, medium, large.

% SIZE=enormous node env.js --size large
{ size: 'large' }

Other Implementations

For interest, examples of other frameworks and products with environment variable support of varying sorts:

ChangeLog

  • add Option support for values from environment variables using .env()

@shadowspawn shadowspawn marked this pull request as ready for review Aug 22, 2021
lib/command.js Outdated Show resolved Hide resolved
Copy link
Collaborator

@abetomo abetomo left a comment

LGTM!
Great!

@shadowspawn shadowspawn merged commit 8571a75 into tj:develop Aug 24, 2021
12 checks passed
@shadowspawn shadowspawn added the pending release label Aug 24, 2021
@shadowspawn shadowspawn deleted the feature/env branch Aug 24, 2021
@shadowspawn shadowspawn removed the pending release label Sep 10, 2021
@shadowspawn
Copy link
Collaborator Author

shadowspawn commented Sep 10, 2021

Shipped in Commander v8.2.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants