Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] Reusing options between subcommands and 'main' #1750

Closed
darcyrush opened this issue Jun 9, 2022 · 2 comments
Closed

[question] Reusing options between subcommands and 'main' #1750

darcyrush opened this issue Jun 9, 2022 · 2 comments

Comments

@darcyrush
Copy link

darcyrush commented Jun 9, 2022

I can 'reuse' commands between subcommands nicely, which populates the options in the call backs as expected

const program = createCommand();
  program
    .command('one')
    .description(desc')
    .requiredOption('--reuse-example [reuseExample]', 'Example of reusable option')
    .requiredOption('--example [example]', 'Example of separate required option')
    .action(asyncCallBackOne);
  program
    .command('two')
    .description(desc')
    .requiredOption('--reuse-example [reuseExample]', 'Example of reusable option')
    .action(asyncCallBackTwo);
await program.parseAsync(process.argv);

And when I run help for each I see as expected;

Usage: program one [options]

desc

Options:
  --reuse-example [reuseExample]      Example of reusable option
  --example [example]                 Example of separate required option
  -h, --help                          display help for command
Usage: program two [options]

desc

Options:
  --reuse-example [reuseExample]      Example of reusable option
  -h, --help                          display help for command

However, if i try and reuse options between a sub command and the 'main' program;

const program = createCommand();
  program
    .requiredOption('--reuse-example [reuseExample]', 'Example of reusable option')
    .action(asyncCallBackMain);
  program
    .command('one')
    .description(desc')
    .requiredOption('--reuse-example [reuseExample]', 'Example of reusable option')
    .requiredOption('--example [example]', 'Example of separate required option')
    .action(asyncCallBackOne);
  program
    .command('two')
    .description(desc')
    .requiredOption('--reuse-example [reuseExample]', 'Example of reusable option')
    .action(asyncCallBackTwo);
await program.parseAsync(process.argv);

then the sub commands will always complain of the missing requiredOption - even if it is passed

error: required option '--reuse-example [reuseExample]' not specified

I can work around this my making the 'main' program a subcommand (like 'start'), but I would prefer if I didn't have to invoke a subcommand just to start the main program.

I'm not sure I am creating the 'main' program correctly though. I tried new Command() but with the same outcome. I also tried two separate command instances with two parseAsync(process.argv) calls (one for 'main' and one for the commands), but then commander doesn't register the commands in the second instance.

Linux: Ubuntu 20.04
Commander: 9.3.0
NodeJS: 18.2.0
@shadowspawn
Copy link
Collaborator

shadowspawn commented Jun 9, 2022

A quick answer (time limited).

Options on the program are "global" and get processed when calling a subcommand, so the program consumes your required option and the subcommand does not see it.

To get the behaviour you want, add a subcommand (like start) as you suggested, but also pass configuration to make it the default command to run when no subcommand is specified. Look for isDefault in the README, and here is an example:

(Similar previous issue: #1616)

@darcyrush
Copy link
Author

Apologies, I did try to search beforehand. Thank you for the solution and rapid response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants