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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use consistent option names between program and subcommand #1616

Closed
danieldelcore opened this issue Oct 4, 2021 · 3 comments
Closed

Comments

@danieldelcore
Copy link

danieldelcore commented Oct 4, 2021

Hi there 馃憢

I've noticed that I'm unable to use an option in a subcommand if the option's name is already in use by the parent command.
My aim to use consistent language across both commands.

import { Command, Option } from 'commander';

const program = new Command();

program
  .name('foo')
  .usage('[global options] <file-paths>...')
  .option(
    '-t, --transform <value>',
    'The transform to run, will prompt for a transform if not provided and no module is passed',
  )
  .action((options, command) => main(command.args, options));

program
  .command('init [path]')
  .description('creates a new package')
  .requiredOption('--package-name <value>', 'Name of the package')
  .option('-t, --transform <value>', 'Transform version')
  .option('-p, --preset <value>', 'Preset transfrom')
  .action((path, options) => console.log(path, options));

Output:

$ yarn start:codemods init --package-name bar --transform foo --preset fooo src/dir

- src/dir { packageName: 'bar', transform: 'foo' preset: 'fooo' }
+ src/dir { packageName: 'bar', preset: 'fooo' }

If I comment out the "transform" option on the parent I get the expected result.

Reproducible on versions: 7.2.0 & 8.2.0

@danieldelcore danieldelcore changed the title Unable to use option names shared between program and subcommand Unable to use consistent option names between program and subcommand Oct 4, 2021
@shadowspawn
Copy link
Collaborator

Is your "parent command" effectively an independent command with its own options separate from the subcommands? (I think so from your example.)

A tidy way of doing this is moving your "parent command" to a subcommand, and making this new subcommand the default command using isDefault configuration. This keeps its options separate from the other commands.

https://github.com/tj/commander.js/blob/master/examples/defaultCommand.js

@danieldelcore
Copy link
Author

Oooooh I never thought about that. Ok I'll give that a go now! Thanks for the prompt response!

@danieldelcore
Copy link
Author

Works a treat!

For future reference this was the working code:

program
-  .name('foo')
+  .command('foo', { isDefault: true })
  .usage('[global options] <file-paths>...')
  .option(
    '-t, --transform <value>',
    'The transform to run, will prompt for a transform if not provided and no module is passed',
  )
  .action((options, command) => main(command.args, options));

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