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

Problem with nested commands #386

Closed
foxx opened this issue Mar 31, 2015 · 7 comments
Closed

Problem with nested commands #386

foxx opened this issue Mar 31, 2015 · 7 comments
Assignees
Milestone

Comments

@foxx
Copy link
Contributor

foxx commented Mar 31, 2015

This seems to also be affecting another user on SO.

The output of options.parent.args seems to be malformed, the second element in the list appears to be a circular reference to itself, where as rawArgs seems to contain the correct items. Had a look at parseOptions in the source but the code isn't very clear in terms of documented logic.

At the very least this would be worthy of a docs update, but as I'm not too sure why the problem is happening, I'm reluctant to sent a PR fix.

Thoughts?

Sample code

  var program = require('commander');

  program
    .version(version)
    .option('-v, --verbose', 'Enable verbose output')
    .usage('[options] [command]')

  program
    .command('runserver <args>')
    .description('run websockets server')
    .action(function(env, options){
      console.log(options.parent.rawArgs);
      console.log(options.parent.args);
    });

  program.parse(process.argv);

Output

$ node bin/boards-server.js -v runserver 1 2 3 4 5 6 7 8 9
[ 'node',
  '/vagrant/server/bin/boards-server.js',
  '-v',
  'runserver',
  '1',
  '2',
  '3',
  '4',
  '5',
  '6',
  '7',
  '8',
  '9' ]
[ '1',
  { commands: [],
    options: [],
    _execs: [],
    _allowUnknownOption: false,
    _args: [ [Object] ],
    _name: 'runserver',
    parent:
     { commands: [Object],
       options: [Object],
       _execs: [],
       _allowUnknownOption: false,
       _args: [],
       _name: 'boards-server',
       Command: [Function: Command],
       Option: [Function: Option],
       _version: <Buffer 30 2e 30 2e 31>,
       _events: [Object],
       _usage: '[options] [command]',
       rawArgs: [Object],
       verbose: true,
       args: [Circular] },
    _description: 'run websockets server' },
  '3',
  '4',
  '5',
  '6',
  '7',
  '8',
  '9' ]
@arboleya
Copy link

I'm not using nested commands but still I'm facing this [Circular] thing on my remaining args.

Program

var program = require('commander');

program
  .version(require('../package.json').version)
  .usage('<input> <output> [vars...]')
  .arguments('[input] [output]')
  .action(function(input, output, vars){
    console.log('input', input);
    console.log('output', output);
    console.log('vars', vars);
  })
  .parse(process.argv);

Execution

$ program a b c=1 d=2 e=3

Output

input ->  a
output ->  b
vars ->  { commands: [],
  options: 
   [ { flags: '-V, --version',
       required: 0,
       optional: 0,
       bool: true,
       short: '-V',
       long: '--version',
       description: 'output the version number' } ],
  _execs: [],
  _allowUnknownOption: false,
  _args: 
   [ { required: false, name: 'input', variadic: false },
     { required: false, name: 'output', variadic: false } ],
  _name: 'condilation',
  Command: [Function: Command],
  Option: [Function: Option],
  _version: '1.0.0',
  _events: { version: [ [Function], [Function] ], '*': [Function] },
  _usage: '<input> <output> [vars...]',
  rawArgs: 
   [ 'node',
     '/this/is/the/script/path',
     'a',
     'b',
     'x=1',
     'y=2',
     'z=3' ],
  args: [ 'a', 'b', [Circular], 'y=2', 'z=3' ] }

Conclusion

Not sure if I should ever skip this [Circular] argument, or not.

@mattwilliams
Copy link

Having the same issue. Wondering what is the solution? I also see: variadic: false... which is not mentioned in the example code.

@KevinLeigh
Copy link

KevinLeigh commented Mar 17, 2019

Hey @foxx, @arboleya, @mattwilliams

For nested commands I found the following to work well for me ->

program.command('rootCommand')
  .action(withErrorHandler.bind(this, async function(cmd) {
    console.info('Executing rootCommand!');
}));

program.command('rootCommand:subCommand')
  .action(withErrorHandler.bind(this, async function(cmd) {
    console.info('Executing subCommand!');
}));

program.command('rootCommand:subCommand2')
  .action(withErrorHandler.bind(this, async function(cmd) {
    console.info('Executing subCommand 2!');
}));

The example above shows a program that has a root command with two subcommands.Doing it this way allows for independent configuration/options for subcommands and root command. The reason it works is because CommanderJS is creating a new command for each sub command and root command.

Usages

Execute root command:

{yourProgram} rootComand
  • Execute sub command
{yourProgram} rootComand:subCommand
  • Execute sub command 2
{yourProgram} rootComand:subCommand2

P.S. Hope this is what you are looking for :)

@shadowspawn shadowspawn self-assigned this Aug 11, 2019
@shadowspawn
Copy link
Collaborator

Working on this currently.

@shadowspawn
Copy link
Collaborator

There are improvements on the develop branch for the next release (#1030 and #1048).

@shadowspawn
Copy link
Collaborator

v4.0.0-0 prerelease published: #1067

@shadowspawn
Copy link
Collaborator

v4.0.0 has been released with a fix for program.args which was getting the command appended (matching the arguments passed to the action handler).

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

5 participants