yargs / yargs

yargs the modern, pirate-themed successor to optimist.
https://yargs.js.org/
MIT License
11.09k stars 992 forks source link

How to convert command from alias to full name programmatically? #2107

Open MurzNN opened 2 years ago

MurzNN commented 2 years ago

I have several command described in yargs with multiple alias, and after command processing is finished, I need to do some more things with this command manually.

So I have a comparison like this

const myYargs = yargs(process.argv.slice(2))
  .command(["command1", "c1", "c"], "Command 1", {},  async (argv) => { console.log("Command 1 executed");  })
  .command(["command2", "c2", "cc"], "Command 2", {},  async (argv) => { console.log("Command 2 executed");  });

const argv = await myYargs.parseAsync();

if (argv._[0] == 'command1') {
  console.log("Command 1 post-execute actions");
}

and it works well if I use full command1 name of command.

But it fails if I use aliases like "c1" or "c", without describing all aliases in that if construction...

To solve this problem I need to somehow convert alias to full command name via yargs API. Or maybe anyone can recommend some other solution?

MurzNN commented 2 years ago

Maybe there is a way to get list of all declared commands from myYargs object, something like myYargs.getAllCommands() or myYargs.getCommandObjectByName('command1')?

MurzNN commented 2 years ago

At now I've implemented this via a little of boilerplate:

const commandsAliases = {
  command1: ["c1", "c"],
  command2: ["c2", "cc"],
};

function getCommand(nameOrAlias) {
  if (commandsAliases[nameOrAlias]) {
    return nameOrAlias;
  }
  for (const command in commandsAliases) {
    if (commandsAliases[command].indexOf(nameOrAlias) != -1) {
      return command;
    }
  }
  return nameOrAlias;
}

const myYargs = yargs(process.argv.slice(2))
  .command(["command1", ...(commandsAliases["command1"] ?? [])], "Command 1", {},  async (argv) => { console.log("Command 1 executed");  })
  .command(["command2", ...(commandsAliases["command2"] ?? [])], "Command 2", {},  async (argv) => { console.log("Command 2 executed");  });

const argv = await myYargs.parseAsync();

if (getCommand(argv._[0]) == 'command1') {
  console.log("Command 1 post-execute actions");
}

But will be glad to have better solution.

bcoe commented 2 years ago

Hey @MurzNN, this is functionality we often need internally, but I don't think we have it exposed for folks using yargs (also I don't know if we have a common helper we use internally for looking up all aliases consistently).

I think this could be a public method worth adding.