« get me outta code hell

make parseOptions code a bit more legible - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-01-16 18:47:49 -0400
committer(quasar) nebula <qznebula@protonmail.com>2023-01-16 18:47:49 -0400
commitda564121c31235f9000f09dd6f9d922b5623249e (patch)
tree778be0c661abba671949ff31d7a16ccff31cda45
parentacecaa1ecd52af8b028a671b8933c47c8018d4ec (diff)
make parseOptions code a bit more legible
-rw-r--r--src/util/cli.js69
1 files changed, 43 insertions, 26 deletions
diff --git a/src/util/cli.js b/src/util/cli.js
index f1a31900..1ddc90e0 100644
--- a/src/util/cli.js
+++ b/src/util/cli.js
@@ -64,8 +64,10 @@ export async function parseOptions(options, optionDescriptorMap) {
   // options is the array of options you want to process;
   // optionDescriptorMap is a mapping of option names to objects that describe
   // the expected value for their corresponding options.
-  // Returned is a mapping of any specified option names to their values, or
-  // a process.exit(1) and error message if there were any issues.
+  //
+  // Returned is...
+  // - a mapping of any specified option names to their values
+  // - a process.exit(1) and error message if there were any issues
   //
   // Here are examples of optionDescriptorMap to cover all the things you can
   // do with it:
@@ -95,11 +97,10 @@ export async function parseOptions(options, optionDescriptorMap) {
   // ['--directory', 'apple'] -> {'directory': 'apple'}
   // ['--directory', 'artichoke'] -> (error)
   // ['--files', 'a', 'b', 'c', ';'] -> {'files': ['a', 'b', 'c']}
-  //
-  // TODO: Be able to validate the values in a series option.
 
   const handleDashless = optionDescriptorMap[parseOptions.handleDashless];
   const handleUnknown = optionDescriptorMap[parseOptions.handleUnknown];
+
   const result = Object.create(null);
   for (let i = 0; i < options.length; i++) {
     const option = options[i];
@@ -107,6 +108,7 @@ export async function parseOptions(options, optionDescriptorMap) {
       // --x can be a flag or expect a value or series of values
       let name = option.slice(2).split('=')[0]; // '--x'.split('=') = ['--x']
       let descriptor = optionDescriptorMap[name];
+
       if (!descriptor) {
         if (handleUnknown) {
           handleUnknown(option);
@@ -116,36 +118,49 @@ export async function parseOptions(options, optionDescriptorMap) {
         }
         continue;
       }
+
       if (descriptor.alias) {
         name = descriptor.alias;
         descriptor = optionDescriptorMap[name];
       }
-      if (descriptor.type === 'flag') {
-        result[name] = true;
-      } else if (descriptor.type === 'value') {
-        let value = option.slice(2).split('=')[1];
-        if (!value) {
-          value = options[++i];
-          if (!value || value.startsWith('-')) {
-            value = null;
-          }
+
+      switch (descriptor.type) {
+        case 'flag': {
+          result[name] = true;
+          break;
         }
-        if (!value) {
-          console.error(`Expected a value for --${name}`);
-          process.exit(1);
+
+        case 'value': {
+          let value = option.slice(2).split('=')[1];
+          if (!value) {
+            value = options[++i];
+            if (!value || value.startsWith('-')) {
+              value = null;
+            }
+          }
+
+          if (!value) {
+            console.error(`Expected a value for --${name}`);
+            process.exit(1);
+          }
+
+          result[name] = value;
+          break;
         }
-        result[name] = value;
-      } else if (descriptor.type === 'series') {
-        if (!options.slice(i).includes(';')) {
-          console.error(
-            `Expected a series of values concluding with ; (\\;) for --${name}`
-          );
-          process.exit(1);
+
+        case 'series': {
+          if (!options.slice(i).includes(';')) {
+            console.error(`Expected a series of values concluding with ; (\\;) for --${name}`);
+            process.exit(1);
+          }
+
+          const endIndex = i + options.slice(i).indexOf(';');
+          result[name] = options.slice(i + 1, endIndex);
+          i = endIndex;
+          break;
         }
-        const endIndex = i + options.slice(i).indexOf(';');
-        result[name] = options.slice(i + 1, endIndex);
-        i = endIndex;
       }
+
       if (descriptor.validate) {
         const validation = await descriptor.validate(result[name]);
         if (validation !== true) {
@@ -167,10 +182,12 @@ export async function parseOptions(options, optionDescriptorMap) {
         }
         continue;
       }
+
       if (descriptor.alias) {
         name = descriptor.alias;
         descriptor = optionDescriptorMap[name];
       }
+
       if (descriptor.type === 'flag') {
         result[name] = true;
       } else {