Skip to content

On command and subcommand reusability and setting inheritance #1916

Closed
@aweebit

Description

Is it expected behavior that parse() / parseAsync() are only correctly callable once, since the command's properties get polluted with the result of the previous call?

I think it should not be expected. Use cases for repeated calls include testing and interactive command parsing.

Here is an example:

program
  .option('-a')
  .option('-b');

program.parse(['-a'], { from: 'user' });
program.parse(['-b'], { from: 'user' });

console.log(program.opts()); // { a: true, b: true }

If it is not expected, a possible solution is to do a cleanup at the beginning of parse() / parseAsync().

Is it expected behavior that explicitly constructed subcommands are tightly bound to one parent command and cannot be used as stand-alone commands or as subcommands of multiple parent commands?

Here is an example:

const sub = new Command('sub')
  .action(() => {});

program
  .hook('preAction', (_, actionCommand) => {
    console.log('preAction', actionCommand.args[0]);
  })
  .addCommand(sub);

// preAction 1 is logged despite calling sub as stand-alone command
sub.parse(['1'], { from: 'user' });

// preAction 2 is logged as expected
program.parse(['sub', '2'], { from: 'user' });

const anotherParent = new Command()
  .addCommand(sub);

// preAction 3 is not logged since sub has been reused as a subcommand of anotherParent 
program.parse(['sub', '3'], { from: 'user' });

If it is not expected, a possible solution is to not set the parent property on subcommands in command() and addCommand() but in _dispatchSubcommand() instead, and unset it before returning.

If it is expected, an error should be thrown when trying to parse or adopt a command that already has a parent.

Is it expected behavior that implicitly constructed subcommands added with command() only inherit settings upon construction?

Here is an example:

const sub = program.command('sub');
program.allowExcessArguments(false);

console.log(program._allowExcessArguments); // false
console.log(sub._allowExcessArguments); // true

program.parse(['sub', 'abc'], { from: 'user' }); // succeeds

If it is not expected, a possible solution is to not call copyInheritedSettings() on subcommands added with command() upon construction but in _dispatchSubcommand() instead.

If it is expected, a note on this in the docs would be nice.

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions