I'm trying to implement prompting users for missing required args/mandatory options.
I thought I could use a preSubcommand hook, change process.argv with prompts, and then allow commander to parse the updated argv.
My hook gets executed before any exit however, After the complete of my hook's callback, I will get this error: error: required option '--foo' not specified.
It seems that parsing continues after the hook on the old process.argv.
For example my-cli subcommand --foo bar will work fine.
my-cli subcommand will prompt for foo and push it to process.argv inside the hook but then exit with the error above.
Any ideas? I tried to suppress this error with exitOverride and re-calling parse afterwards, but my callback is not being reached. Surrounding in try-catch doesn't work either.
Here's my code:
program
.name('cli')
.description('foo')
.version(version, '-v, --version')
.addCommand(sub)
.hook('preSubcommand', async (program, subcommand) => {
await promptForMissingArgs(program, subcommand);
console.log('here');
console.log(process.argv);
program.parse(process.argv); // called again with correct process.argv but still exits
})
.exitOverride((exitCode) => {
console.log(`Exiting with code ${exitCode.exitCode}`); // not reached
// if (exitCode.exitCode !== 0) {
// program.parse(process.argv);
// }
});
// parse command line arguments and execute command
try {
program.parse(process.argv);
} catch (error) {
console.log('here'); // doesn't reach here
console.error(error);
}
From the docs I see this: if the first arg is a subcommand call preSubcommand hooks pass remaining arguments to subcommand, and process same way
https://github.com/tj/commander.js/blob/HEAD/docs/parsing-and-hooks.md
Is it because my hook is async?
Instead of trying to change process.argv, I was able to set options during
preSubcommandhook. I was not able to find a way to change argument values so I settled with options.@shadowspawn answer is also valid but I have multiple subcommands so I chose to keep my prompting in the shared
preSubcommandhook rather thanpreAction. This also let me keep options as mandatory because they are not checked yet at this stage in the parsing lifecycleWith
promptForMissingArgsimplementation something like this: