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

One and only one of X options (demandOption + conflicts) #1093

Open
bkrodgers opened this issue Mar 21, 2018 · 1 comment
Open

One and only one of X options (demandOption + conflicts) #1093

bkrodgers opened this issue Mar 21, 2018 · 1 comment

Comments

@bkrodgers
Copy link

bkrodgers commented Mar 21, 2018

Am I missing something, or is there no way to specify that of option X, Y, and Z, I want to require one but not allow more than one? That is, other than using a .check() function? I can't use demandOption, because then they both have to be specified. I can use conflicts to enforce the mutual exclusivity, but looks like I need to use check to provide a function to do the check that at least one of the group has been defined. That's not a huge deal, though that then doesn't automatically give any hints in the right column of the help output.

Could a .demandOneOfOption(options...) be added to make this a little easier and perhaps integrate in with .help()?

@asnaseer-resilient
Copy link

asnaseer-resilient commented May 10, 2019

I created a checking function for required mutually exclusive options as follows (in TypeScript):

const demandOneOfOption = (...options: string[]) => (argv: {}) => {
  const count = options.filter(option => argv[option]).length;
  const lastOption = options.pop();

  if (count === 0) {
    throw new Error(`Exactly one of the arguments ${options.join(', ')} and ${lastOption} is required`);
  }
  else if (count > 1) {
    throw new Error(`Arguments ${options.join(', ')} and ${lastOption} are mutually exclusive`);
  }

  return true;
};

You can call this multiple times as follows:

const argv = require('yargs')
  ...
  .option('fast', { type: boolean, ... })
  .option('medium', { type: boolean, ... })
  .option('slow', { type: boolean, ... })
  .option('xml', { type: boolean, ... })
  .option('json', { type: boolean, ... })
  .check(demandOneOfOption('fast', 'medium', 'slow'))
  .check(demandOneOfOption('xml', 'json'))
  .argv;

You would not need to use conflicts with the above as my checking function already performs this check.

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