From 76d9de17781b849d979422761b13dcf286fba0af Mon Sep 17 00:00:00 2001 From: C-3PO Date: Thu, 25 Oct 2018 04:34:11 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=20Always=20return=20fail=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/index.ts | 4 ++-- src/initState.ts | 6 ++--- src/parseArgument.ts | 38 ++++++++++++++++---------------- src/runPreParseHook.ts | 3 +-- src/verifyAndStoreOptionValue.ts | 8 +++---- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 276e4c4..4825a21 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ This module parses the command line arguments into a JavaScript object, and veri The main goal is to keep all the complexity and error handling inside this module, so that all command line applications only need to provide a couple lines of specification and do not have to worry about verifying the input or checking for `undefined`. # Installation + For this tool to work, the TypeScript compiler must be globally installed: ```bash diff --git a/src/index.ts b/src/index.ts index 0ba7f3f..3e0b431 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,13 +23,13 @@ export default function parseArguments( // argumentName must be cleared to '' after the value is read, so if it is not an empty string, the value was missing if (lastOption !== '') { - fail(`Option "${lastOption}" was not followed by a value.`); + return fail(`Option "${lastOption}" was not followed by a value.`); } //check if any entry in requiredArguments was not set for (const optName in requiredOptions) { if (spec.hasOwnProperty(optName) && requiredOptions[optName] === false) { - fail(`Missing option "${optName}" even though it is required.`); + return fail(`Missing option "${optName}" even though it is required.`); } } diff --git a/src/initState.ts b/src/initState.ts index ad02d68..c77bf8a 100644 --- a/src/initState.ts +++ b/src/initState.ts @@ -13,16 +13,16 @@ export default function initState(spec: { [key: string]: IOption }) { for (const longOption in spec) { if (spec.hasOwnProperty(longOption)) { if (longOption === '') { - failFunction(`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.`); + return failFunction(`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]+)*$/)) { - failFunction(`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.`); + return failFunction(`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) { - failFunction(`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.`); + return failFunction(`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; } diff --git a/src/parseArgument.ts b/src/parseArgument.ts index c4fb3d8..963c64f 100644 --- a/src/parseArgument.ts +++ b/src/parseArgument.ts @@ -9,20 +9,20 @@ export default function parseArgument( requiredOptions: { [key: string]: boolean }, shortToLongLookup: { [key: string]: string }, }, - option: string, + previousOption: string, arg: string, ): string { - if (option === '') { - /** We expect a name, must be one of: - * - `--name value` - * - `--name=value` - * - `-n value` - * - `-n=value` + if (previousOption === '') { + /** We expect an option, must be one of: + * - `--option value` + * - `--option=value` + * - `-o value` + * - `-o=value` */ if (arg === '-' || arg === '--') { - fail(`Empty option "-" or "--" is not supported.`); + return fail(`Empty option "-" or "--" is not supported.`); } else if (arg.startsWith('--')) { //long argument - option = arg.substr(2); + let option = arg.substr(2); let value; //If there's a =, immediately read the value if (option.indexOf('=') !== -1) { @@ -30,15 +30,16 @@ export default function parseArgument( } //Check that argument name is valid if (spec[option] === undefined) { - fail(`Unknown option "--${option}".`); + 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}); - option = ''; + return ''; } + return option; } else if (arg.startsWith('-')) { //short argument - option = arg.substr(1); + let option = arg.substr(1); let value; //If there's a =, immediately read the value if (option.indexOf('=') !== -1) { @@ -46,21 +47,20 @@ export default function parseArgument( } //Check that argument name is valid if (shortToLongLookup[option] === undefined) { - fail(`Unknown short option "-${option}".`); + 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}); - option = ''; + return ''; } + return option; } else { - fail(`Arguments must be preceded by an option but there was no option in front of "${arg}".`); + 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, value: arg, verify: spec[option].verify, message: spec[option].message, fail, outputArgs, requiredOptions}); - option = ''; + verifyAndStoreOptionValue({option: previousOption, value: arg, verify: spec[previousOption].verify, message: spec[previousOption].message, fail, outputArgs, requiredOptions}); + return ''; } - - return option; } diff --git a/src/runPreParseHook.ts b/src/runPreParseHook.ts index 15d8a4d..d2542a2 100644 --- a/src/runPreParseHook.ts +++ b/src/runPreParseHook.ts @@ -12,7 +12,6 @@ export default function runPreParseHook({ args, preParseHook, fail }: { const modifiedArgs = preParseHook(args, fail); return modifiedArgs !== undefined ? modifiedArgs : args; } catch (error) { - fail(`Could not run pre-parse hook, encountered error: ${String(error)}.`); - return []; + return fail(`Could not run pre-parse hook, encountered error: ${String(error)}.`); } } diff --git a/src/verifyAndStoreOptionValue.ts b/src/verifyAndStoreOptionValue.ts index 673d479..ef41238 100644 --- a/src/verifyAndStoreOptionValue.ts +++ b/src/verifyAndStoreOptionValue.ts @@ -24,16 +24,16 @@ export default function verifyAndStoreOptionValue({ try { const customMessage = message(value); if (customMessage !== undefined && customMessage !== '') { - fail(customMessage); + return fail(customMessage); } } catch (error) { - fail(`Invalid value set for option "${option}": "${value}". Could not show custom error message: ${String(error)}`); + return fail(`Invalid value set for option "${option}": "${value}". Could not show custom error message: ${String(error)}`); } } - fail(`Invalid value set for option "${option}": "${value}".`); + return fail(`Invalid value set for option "${option}": "${value}".`); } } catch (error) { - fail(`Invalid value set for option "${option}", the validation of "${value}" failed: ${String(error)}`); + return fail(`Invalid value set for option "${option}", the validation of "${value}" failed: ${String(error)}`); } //Remember the value, and if it is a required argument, mark that we have encountered it