argument-parser/src/initState.ts

49 lines
2.4 KiB
TypeScript

import failWithError from './failWithError';
import IOption from './IOption';
const fail = failWithError.bind(null, '');
export default function initState(spec: { [key: string]: IOption }) {
//The parsed arguments that are returned by this function
const outputArgs: { [key: string]: string } = {};
//Create a lookup table to find a long option when given the short option, and to check if all required options are set
const shortToLongLookup: { [key: string]: string } = {};
const requiredOptions: { [key: string]: boolean } = {};
for (const longOption in spec) {
if (spec.hasOwnProperty(longOption)) {
if (longOption === '') {
fail(`The long option may not be an empty string. This is a bug in the source code of the script that you tried to call.`);
}
if (!longOption.match(/^[a-z0-9]+(-[a-z0-9]+)*$/)) {
fail(`The long option "${longOption}" must only contain alpha-numeric characters, optionally separated by hyphens. This is a bug in the source code of the script that you tried to call.`);
}
const shortOption = spec[longOption].short;
if (shortOption !== undefined && shortOption !== '') {
if (shortOption.length > 1) {
fail(`Short options must only be one character long but the short option "${shortOption}" for "${longOption}" was ${shortOption.length} characters long. This is a bug in the source code of the script that you tried to call.`);
}
shortToLongLookup[shortOption] = longOption;
}
//If a default value is given, use the default value (it can be overridden later), otherwise mark argument as being required
const defaultValue = spec[longOption].default;
if (defaultValue !== undefined) {
outputArgs[longOption] = defaultValue;
} else {
requiredOptions[longOption] = false;
}
}
}
const usage = `./${process.argv[1].substr(process.argv[1].lastIndexOf('/') + 1)} [options]\nOPTIONS\n${
Object.entries(spec).map(([key, {default: defaultValue, short, description}]) => (
` ${(defaultValue === undefined) ? '' : '['}${(short !== undefined && short !== '') ? `-${short}, ` : ''}--${key} <value>${(defaultValue === undefined) ? '' : `], defaults to "${defaultValue}"`}${(description !== undefined && description !== '') ? `\n ${description}` : ''}`
)).join('\n')
}`;
const failFunction = failWithError.bind(null, usage);
return { outputArgs, shortToLongLookup, requiredOptions, failFunction };
}