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

Global Options #476

Closed
alex-phillips opened this issue Dec 9, 2015 · 13 comments
Closed

Global Options #476

alex-phillips opened this issue Dec 9, 2015 · 13 comments

Comments

@alex-phillips
Copy link

Is there a way to add global options to a program that is applied to all commands? I'm trying to be able to define a single verbose and quiet flag that is applied not only to the program but to all commands added as well.

I can post sample code if necessary, but I think it's fairly self-explanatory.

@leesei
Copy link

leesei commented Feb 2, 2016

It works as is:

Program
  .version(Pkg.version)
  .description(Pkg.description)
  .options('-v, --verbose', 'be verbose')
  .option('-q, --quiet', 'be quiet')

Program
  .command('search <query>')
  .description('do search')
  .option('-r, --regex', 'use regex')
  .action(function search (query, options) {
    // Program.quite
    // Program.verbose
    // options.regex
  });

@donaldpipowitch
Copy link

Can I write a default action for an option? It is quite nice that I can create a "global option" which is passed to every command, but if I have many commands I don't want to call loggingFramework.setLogLevel(options.quite) everywhere.

I can't do commander.parse(process.argv); commander.opts();, because then the commands action is called before I can do something with opts. But it looks I need to call parse before I can use options correctly.

And it looks like these global options aren't shown in the --help output of a command.

@thetutlage
Copy link

thetutlage commented May 13, 2017

@donaldpipowitch Going through the source code and found this line. https://github.com/tj/commander.js/blob/master/index.js#L393

It seems to be possible as

Program.on('verbose', function () {
  process.env.VERBOSE = this.verbose
})

Program.on('quiet', function () {
  process.env.QUIET = this.quiet
})

Also for options that accept values, the value is passed to the callback function. For example

Program.on('env', function (env) {
  process.env.NODE_ENV = env
})
some-command --env=production

@donaldpipowitch
Copy link

Cool, thanks.

@bencao
Copy link

bencao commented Jan 30, 2019

In addition to @donaldpipowitch's comment, in order to listen on the option event, we could use:

program
  .option("--disable-tty", "disable tty")
  .on("option:disable-tty", function() {
    // do something here
  })

@shadowspawn
Copy link
Collaborator

The original question got answered, and I don't think there will be action due to the subsequent comments.

Feel free to open a new issue if it comes up again, with new information and renewed interest.

Thank you for your contributions.

@shadowspawn
Copy link
Collaborator

Opened poll on possible enhancements to global options: #1551

@percenuage
Copy link

Hello, I think it should be a better if the global options are merged with local options in order to access it when we use a different file for commands. See an example:

program
  .version(version, '-v, --version', 'Output the current version')
  .option('-g, --global', 'Global')

program
  .command('sh')
  .option('-l, --local', 'Local')
  .action(function (args) {
    console.log(args.local) // true
    console.log(program.global) // true
    console.log(args.global) // Should be "true" as well but it's "undefined"
  });

I'm using commander v8.2

@jerrywithaz
Copy link

This is my work around at the moment:

class CustomCommand extends Command {
  constructor(...args) {
    super(...args);
    this.addBucketOption(); // adds the option for all commands created
  }

  createCommand(...args) {
    return new CustomCommand(...args);
  }

  addBucketOption() {
    return this.option(
      '--bucket <name>',
      'The google cloud storage bucket to download backups from.',
      backup_bucket
    );
  }
  }
}

const program = new CustomCommand('my-program');

@shadowspawn
Copy link
Collaborator

Opened a draft PR for .addCommonOption() #1670

@WoZ
Copy link

WoZ commented Aug 11, 2023

For everyone who tries to find the right way to access the global options in the action handler...

Here is a working example for version 11+

const program = new Command();
program.description('Tool to analyze Feed data');
program.addOption(new Option('--loglevel <loglevel>', 'Logging level').choices(['debug', 'info', 'warn', 'error']).default('error'));

program
    .command('history')
    .description('Generates history')
    .addOption(new Option('--offset <offset>', 'Offset to start from').default(0))
    .action(args => {
        console.log(program.opts());
        console.log(args);
    });

program.parse();

The output is

$ node analyze.js --loglevel info history 
{ loglevel: 'info' }
{ offset: 0 }

@shadowspawn
Copy link
Collaborator

Another approach now available is .optsWithGlobals() to combine the global and local options:

   .action((options, cmd) => {
      console.log(options);
      console.log(cmd.optsWithGlobals());
}

@teto
Copy link

teto commented Nov 17, 2023

maybe because I had positional args as well but I had to do:

   .action((options, cmd, toto) => {
      console.log(options);
      console.log(cmd);
      console.log(toto.optsWithGlobals());
    })

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

No branches or pull requests

10 participants