66 lines
2.6 KiB
TypeScript
66 lines
2.6 KiB
TypeScript
import IOption from './IOption';
|
|
import verifyAndStoreOptionValue from './verifyAndStoreOptionValue';
|
|
|
|
export default function parseArgument(
|
|
{ spec, fail, outputArgs, requiredOptions, shortToLongLookup }: {
|
|
spec: { [key: string]: IOption },
|
|
fail: (errorMessage: string) => never,
|
|
outputArgs: { [key: string]: string },
|
|
requiredOptions: { [key: string]: boolean },
|
|
shortToLongLookup: { [key: string]: string },
|
|
},
|
|
previousOption: string,
|
|
arg: string,
|
|
): string {
|
|
if (previousOption === '') {
|
|
/** We expect an option, must be one of:
|
|
* - `--option value`
|
|
* - `--option=value`
|
|
* - `-o value`
|
|
* - `-o=value`
|
|
*/
|
|
if (arg === '-' || arg === '--') {
|
|
return fail(`Empty option "-" or "--" is not supported.`);
|
|
} else if (arg.startsWith('--')) { //long argument
|
|
let option = arg.substr(2);
|
|
let value;
|
|
//If there's a =, immediately read the value
|
|
if (option.indexOf('=') !== -1) {
|
|
[option, value] = option.split('=', 2);
|
|
}
|
|
//Check that argument name is valid
|
|
if (spec[option] === undefined) {
|
|
return fail(`Unknown option "--${option}".`);
|
|
}
|
|
//If value was provided, check that value is correct and remove name for next loop iteration
|
|
if (value !== undefined) {
|
|
verifyAndStoreOptionValue({option, value, verify: spec[option].verify, message: spec[option].message, fail, outputArgs, requiredOptions});
|
|
return '';
|
|
}
|
|
return option;
|
|
} else if (arg.startsWith('-')) { //short argument
|
|
let option = arg.substr(1);
|
|
let value;
|
|
//If there's a =, immediately read the value
|
|
if (option.indexOf('=') !== -1) {
|
|
[option, value] = option.split('=', 2);
|
|
}
|
|
//Check that argument name is valid
|
|
if (shortToLongLookup[option] === undefined) {
|
|
return fail(`Unknown short option "-${option}".`);
|
|
}
|
|
option = shortToLongLookup[option];
|
|
//If value was provided, check that value is correct and remove name for next loop iteration
|
|
if (value !== undefined) {
|
|
verifyAndStoreOptionValue({option, value, verify: spec[option].verify, message: spec[option].message, fail, outputArgs, requiredOptions});
|
|
return '';
|
|
}
|
|
return option;
|
|
} else {
|
|
return fail(`Arguments must be preceded by an option but there was no option in front of "${arg}".`);
|
|
}
|
|
} else { //We expect a value, can be anything
|
|
verifyAndStoreOptionValue({option: previousOption, value: arg, verify: spec[previousOption].verify, message: spec[previousOption].message, fail, outputArgs, requiredOptions});
|
|
return '';
|
|
}
|
|
}
|