commander.js: Show help if mandatory arguments not used

I have the following code:

const version = JSON.parse(fs.readFileSync(path.join(__dirname, './package.json')) + '').version;

program
.version(version)
.arguments('<engine>')
.option('-u, --url <link>','indicates that the address parameter is to be interpreted as an url (value by default)')
.option('-f, --file <link>','indicates that the address parameter is to be interpreted as a file')
.action(main)

program.parse(process.argv);
if (!process.argv.slice(2).length) {
    program.outputHelp();
}

function main(engine){
    console.log(engine);
    if(program.file) {
        renderer.execute(program.file,engine, {file: true}).then(console.log);
    } else {
        renderer.execute(program.url, engine).then(console.log).done();
    }
};

I was trying to have the program output the help text if the argument engine is not specified. Is there any built-in way to do this? At the moment the code works perfectly if I specify the engine. but if I just execute with any arguments then nothing is shown.

Thanks for taking the time to read this.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 15 (4 by maintainers)

Most upvoted comments

And here is a more specific implementation of .exitOverride to look for the error of interest:

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

program.exitOverride((err) => {
  if (err.code === 'commander.missingArgument') {
    program.outputHelp();
  }
  process.exit(err.exitCode);
});

program
  .arguments('<engine>')
  .option('-u, --url <link>','indicates that the address parameter is to be interpreted as an url (value by default)')
  .action((engine) => {
    console.log(`Action called with ${engine}`);
});

program.parse();

I had to remind myself what .parseOptions returns. This is the pre-flighting I had in mind to check for no arguments after top-level parse.

const { Command } = require("commander");

function makeProgram() {
  const program = new Command();
  program
    .arguments('<engine>')
    .option('-u, --url <link>','indicates that the address parameter is to be interpreted as an url (value by default)')
    .option('-f, --file <link>','indicates that the address parameter is to be interpreted as a file')
    .action((engine) => {
        console.log(`Action called with ${engine}`);
    });
    return program;
  }

if (makeProgram().parseOptions(process.argv).operands.length <= 2) {
  makeProgram().help();
}

makeProgram().parse(process.argv);