tj / commander.js

node.js command-line interfaces made easy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ability to get subcommand executed

Zamiell opened this issue · comments

Hello,

This is a feature request to get the subcommand that was run.

Some of my subcommands need to exit the program, and others don't.

Thus, I am now using the following hacky code:

  const executedProgram = await program.parseAsync(); // Will run the subcommand action.

  if (!("_defaultCommandName" in executedProgram)) {
    throw new Error(
      'Failed to find the "_defaultCommandName" field from the parsed command.',
    );
  }
  if (typeof executedProgram._defaultCommandName !== "string") {
    throw new Error(
      `Failed to parse the "_defaultCommandName" field since it was of type: ${typeof executedProgram._defaultCommandName}`,
    );
  }

  const firstArg = executedProgram.args[0];

  const command = firstArg === undefined || firstArg === "" || firstArg.startsWith("-")
    ? executedProgram._defaultCommandName
    : firstArg;

  if (shouldExitProgramAfterCommand(command)) {
    process.exit();
  }

Obviously, this is quite ugly, since I am having to rely on internal variables that are prefixed with an underscore. I think a better API for commander.js would be something like this:

  const executedProgram = await program.parseAsync(); // Will run the subcommand action.
  const command = executedProgram.commandExecuted;

  if (shouldExitProgramAfterCommand(command)) {
    process.exit();
  }

You can use a hook to run code after the action handler, which might suit your use case.

const { program } = require('commander');

program.command('one', { isDefault: true })
  .action(() => { console.log('called one')});

program.command('two')
  .action(() => { console.log('called two')});

program.hook('postAction', (thisCommand, actionCommand) => {
  console.log(`Wonder if we should exit program after ${actionCommand.name()}`);
});

program.parse();
% node index.js
called one
Wonder if we should exit program after one
% node index.js one
called one
Wonder if we should exit program after one
% node index.js two
called two
Wonder if we should exit program after two

Thank you, this does indeed suit my use case. I missed this part of the manual, since I was searching for some variation of "subcommand name". I will close this issue; hopefully it will be useful for future Google searches.