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

How to get options from sub command exes #563

Closed
kahunacohen opened this issue Aug 22, 2016 · 14 comments
Closed

How to get options from sub command exes #563

kahunacohen opened this issue Aug 22, 2016 · 14 comments

Comments

@kahunacohen
Copy link

In my 'foo' sub command file (Eg. pm-foo.js) how do I get hold of the options passed?

pm.js:

...
program
  .version('0.0.1')
  .command('foo [name]', 'desc' {a:'b'})
  .parse(process.argv);

I tried passing parameters after the description parameter, but how do you get hold of them in the pm-foo.js file? I tried printing out name in pm-foo.js too. Any help is appreciated.

@sgen
Copy link

sgen commented Aug 22, 2016

Commander passes the remaining arguments to a child process running the sub command script. You can access them with process.argv

@kahunacohen
Copy link
Author

These are just the remaining arguments on the command-line. How do I get a hold of extra arguments passed after the description argument of command()? In pm-foo.js if I print out process.argv I get ['node', PATH_TO_PM_FOO]. No {'a': 'b'}.

@sgen
Copy link

sgen commented Aug 23, 2016

Commander.command() doesn't actually call a subcommand. It just defines one.

program
  .version('0.0.1')
  .command('foo [name]', 'desc' {a:'b'})
  .parse(process.argv);

is defining a subcommand called foo. The [name] argument is just for the help message. You're also missing a comma in your example. As for the options the only options mentioned in the docs are opts.noHelp and opts.isDefault, no other arguments are passed.

Your pm-foo.js file might look like this:

var subCommand = require('commander');

subCommand
  .option('-a, --an-option')
  .parse(process.argv);


var args = subCommand.args.slice(2);
var name = args.pop();

if (!name) // ...

if(!subCommand.anOption) // ...

@b4dnewz
Copy link

b4dnewz commented Jan 22, 2018

the main options are not forwarded to the subcommands for example:

pm.js

program
  .name('cli')
  .option('-k, --key <apikey>')

pm-foo.js

program
  .command('list')
  .option('-l, --limit')
  .action(options => {
    console.log(program);
    console.log(options);
    console.log(program.options);
    console.log(program.apikey);
})

cli -k 'ABCD' list

is possible to get the apikey from the "root" command?

@PaulBeaudet

This comment has been minimized.

@b4dnewz
Copy link

b4dnewz commented Feb 9, 2018

@PaulBeaudet can you share a working example? because in my parent property there are no root options, btw the code above is pseudo code, actually is not working it should be like in the example:

pm.js

program
  .name('cli')
  .option('-k, --key <apikey>')
  .command('foo', 'a sub command')
  .parse(process.argv)

pm.foo.js

program
  .option('-l, --limit')
  .parse(process.argv)

console.log(program)
console.log(program.parent) // undefined

In my previous message I did a wrong mesh up of something i'm doing which was very long and I cutted and pasted parts without verify if it was really working, actually the my real code is more like this below:

pm.js

program
  .option('-k, --key', 'the api key')
 .command('section', 'The section subcommands')

pm-section.js

program
 .command('list', 'list section data')
 .option('-l, --limit', 'some limit')
 .action(options => {
  console.log(options) 
 })

and than I use like: pm -k ABCD section list --limit 50

@PaulBeaudet

This comment has been minimized.

@b4dnewz

This comment has been minimized.

@shadowspawn
Copy link
Collaborator

Git-style executable (sub)commands are spawned separate commands. There is not a direct way from the subcommand to get at options that were declared on the outer program, and they are not passed to the subcommand as arguments. (You do have access to the parent command options if you instead use an action handler to implement the command.)

An idea for passing the parent options implicitly is to add them as process environment variables.

pm.js

const program = require("commander");

program
  .option('-k, --key <apikey>')
  .on("option:key", (apikey) => {
    process.env["key"] = apikey;
  })
  .command('foo', 'a sub command')
  .parse(process.argv);

pm-foo.js

console.log(`key is ${process.env["key"]}`);
$ node pm.js foo
key is undefined
$ node pm.js -k hello foo
key is hello

@lucasdiedrich

This comment has been minimized.

@shadowspawn

This comment has been minimized.

@shadowspawn
Copy link
Collaborator

@gitoutthere wondered about a hook with an opportunity to manipulate the arguments before calling the subcommand in #1137

@gitoutthere
Copy link

@gitoutthere wondered about a hook with an opportunity to manipulate the arguments before calling the subcommand in #1137

I managed to make it work within my main command_file.js using below, it parses all the parameters from file and passes it to the sub-command file. Note that I include '--' below and not in the parameters file:

if(program.input) {
  let inputArgs = []
  try {
    let inputArgsObj = JSON.parse(fs.readFileSync(program.input,'utf8'))
    for (let key in inputArgsObj) {
      // push parameters (key) and their values into inputArgs (process.argv) format
      inputArgs.push('--'+key, (typeof inputArgsObj[key] === 'object') ? JSON.stringify(inputArgsObj[key]) : inputArgsObj[key])
    }
    // place inputArgs into process.argv at position 4. Position 1,2 and 3 is ignored by .parse() 
    process.argv.splice(3, 0, ...inputArgs)
  } catch(error) {
    console.error(error.message)
    process.exit(1)
  }
}

@shadowspawn
Copy link
Collaborator

This issue has not seen a lot of activity over the years. It isn't likely to get acted on due to this report.

On a somewhat related note, see also: #1229

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

Thank you for your contributions.

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

7 participants