Last active
April 2, 2020 21:27
-
-
Save dschnare/7baa2c6ef521f20578081f25a22ea1b3 to your computer and use it in GitHub Desktop.
Read a command line option
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Read a command line option. Option names must start with '-'. | |
* | |
* Options: | |
* | |
* `required` Determines if the option must appear on the command line. | |
* | |
* `multi` Determines if the option can be specified more than once on the | |
* command line. Causes the return value to be an array. | |
* | |
* `converter` The conversion function to use to convert an option's value. | |
* | |
* @example | |
* const args = process.args.slice(2) | |
* const flavors = readOption([ '--flavor' ], args, { multi: true }) | |
* @template T | |
* @param {string[]} names The valid option names on the command line | |
* @param {string[]} args The command line arguments without the program and script name | |
* @param {{ required?: boolean, multi?: boolean, converter: (value:string) => T }} [options] | |
* @return {T|T[]} | |
*/ | |
const readOption = (names, args, { required = false, multi = false, converter = x => x } = {}) => { | |
const values = [] | |
names.forEach(name => { | |
const index = args.findIndex(arg => arg.split('=')[0] === name) | |
if (index >= 0) { | |
let value = args[index].indexOf('=') > 0 | |
? args[index].split('=').slice(1).join('=') | |
: (args[index + 1] || '') | |
if (value.startsWith('-')) { | |
value = '' | |
} | |
values.push(value) | |
} | |
}) | |
if (required && !values.length) { | |
throw new Error(`Command line option ${names[0]} is required`) | |
} | |
if (!multi && values.length > 1) { | |
throw new Error(`Command line option ${names[0]} does not support mulitple values`) | |
} | |
const convertedValues = values.map(converter) | |
const value = multi ? convertedValues : convertedValues.pop() | |
return value | |
} | |
/** | |
* Read a command line flag. Flag names must start with '-'. | |
* | |
* @example | |
* const args = process.args.slice(2) | |
* const reportOnly = readOption.flag([ '--reportyOnly' ], args) | |
* @param {string[]} names The valid option names on the command line | |
* @param {string[]} args The command line arguments without the program and script name | |
* @param {{ required?: boolean }} [options] | |
* @return {boolean} | |
*/ | |
readOption.flag = (names, args, { required = false } = {}) => { | |
const converter = value => { | |
if (value) { | |
throw new Error(`Command line option ${names[0]} is a flag and cannot have a value`) | |
} | |
return true | |
} | |
const options = { required, multi: false, converter } | |
return readOption(names, args, options) || false | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment