Commander.js: Sub command fails when option placed between sub command and argument

Created on 10 May 2018  路  3Comments  路  Source: tj/commander.js

My code:

#!/usr/bin/env node
const program = require("commander");

program
    .version("0.0.1")
    .command("x <items>")
    .option("-m, --manifest [ bool ]", "save manifest.json", false)
\   .description("description goes here")
    .action((items, cmd) => {
        console.log("option manifest", cmd.manifest);
        console.log("items", items);
     });

program.parse(process.argv);

When I run the following it works:
test-commander x a,b,c -m

But when I run the following it doesn't work:
test-commander x -m a,b,c

and the I get the following error:
__error: missing required argument `items'__

When run with -h the generated help doc indicates that my use case is supported:
Usage: test-commander [options] [command]

Options:

-V, --version      output the version number
-h, --help         output usage information

Commands:

__x [options] description goes here__

So Is this a commander error/generated help doc error or am I wrong in thinking my use case is supported?

Most helpful comment

Well after reading the docs a little more attentively and spying the arguments passed to the action callback handler I realized I was being a total dick :)
I easily got my intended command line structure to work using the following:

const program = require("commander");

program
    .version("0.0.1")
    .option("-i, --ignore [ignores]", "ignore files")
    .option("-m, --manifest [manifest]", "save manifest file");

program
    .command("bust [files]")
    .action(function (files, cmd) {
        console.log("command", "bust");
        console.log("files", files)
        console.log("cmd -i", cmd.parent.ignore);
        console.log("cmd -m", cmd.parent.manifest);
    });

program
    .command("restore [files]")
    .action(function (files, cmd) {
        console.log("command", "restore");
        console.log("files", files)
        console.log("cmd -i", cmd.parent.ignore);
        console.log("cmd -m", cmd.parent.manifest);
    });

program.parse(process.argv);

My only concern at this point is that I am not using a specific commander api but instead I am using knowledge of the arguments structure passed to the action callback gleaned from snooping. I'm afraid that if in a future __commander__ version changes to these arguments structure will break my code. Is there a better way to do this and if so how? And sorry for the false alarm. I will close this out but hope that someone will be kind enough to tell me if there is or isn't a better way to do this.

All 3 comments

BTW
"dependencies": {
"commander": "^2.15.1"
}

Well after reading the docs a little more attentively and spying the arguments passed to the action callback handler I realized I was being a total dick :)
I easily got my intended command line structure to work using the following:

const program = require("commander");

program
    .version("0.0.1")
    .option("-i, --ignore [ignores]", "ignore files")
    .option("-m, --manifest [manifest]", "save manifest file");

program
    .command("bust [files]")
    .action(function (files, cmd) {
        console.log("command", "bust");
        console.log("files", files)
        console.log("cmd -i", cmd.parent.ignore);
        console.log("cmd -m", cmd.parent.manifest);
    });

program
    .command("restore [files]")
    .action(function (files, cmd) {
        console.log("command", "restore");
        console.log("files", files)
        console.log("cmd -i", cmd.parent.ignore);
        console.log("cmd -m", cmd.parent.manifest);
    });

program.parse(process.argv);

My only concern at this point is that I am not using a specific commander api but instead I am using knowledge of the arguments structure passed to the action callback gleaned from snooping. I'm afraid that if in a future __commander__ version changes to these arguments structure will break my code. Is there a better way to do this and if so how? And sorry for the false alarm. I will close this out but hope that someone will be kind enough to tell me if there is or isn't a better way to do this.

If you are still interested, add a comment and I'll make some suggestions. (I came across this looking for issues where options were defined at multiple levels.)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

san-templates picture san-templates  路  5Comments

snitin315 picture snitin315  路  4Comments

shadowspawn picture shadowspawn  路  4Comments

shadowspawn picture shadowspawn  路  5Comments

youurayy picture youurayy  路  5Comments