Repository: rickbergfalk/sqlpad
Pull request #460 (2019-09-01 23:02:30)

Remove separate cli flag keys
This removes the separate `cliFlag` flag key values, opting for using the plain config item key instead. 

For example, this means you need to use `--dbPath` instead of `--dir`, `--baseUrl` instead of `--base-url`. 

Reason for this is to cut down on complexity of implementation and documentation.


Patch:
diff --git a/docs-source/content/posts/installation-and-administration.md b/docs-source/content/posts/installation-and-administration.md
index bcf4a9b9..cf01755c 100644
--- a/docs-source/content/posts/installation-and-administration.md
+++ b/docs-source/content/posts/installation-and-administration.md
@@ -23,35 +23,6 @@ To get help and see parameters:
 
 `sqlpad --help`
 
-
-### A Realistic Example:  
-
-`sqlpad --dir c:/sqlpad/ --port 3000 --passphrase secret-encryption-phrase`
-
-The **dir** argument specifies where to keep the sqlpad query/user/connection files. If not provided, SQLPad will put its files in the user's home directory under /sqlpad/db.
-
-The **port** argument specifies the port on which SQLPad should run. The default is port 80, but that may not be available.
-
-The **passphrase** argument is used to encrypt database connection usernames and passwords, and cookie encryption. If not provided, SQLPad will use the default to at least prevent usernames and passwords from being stored in plaintext. 
-
-If a passphrase is ever changed or forgotten, you'll need to re-add the connection usernames and passwords to each database connection. 
-
-If you ever want to save the arguments you are passing in so you don't have to remember them, you can save them by passing in the ```--save``` argument.
-
-`sqlpad --dir ./sqlpad/ --port 3000 --passphrase secret-encryption-phrase --save`
-
-Then the next time you can simply run...
-
-`sqlpad` 
-
-...and Sqlpad will use directory ./sqlpad, on port 3000, with the proper encryption passphrase.
-
-These settings can be forgotten by running 
-
-`sqlpad --forget`
-
-
-
 ## Administration
 
 Once SQLPad is running, create an initial admin account by navigating to [http://localhost/signup](http://localhost/signup). 
@@ -147,4 +118,4 @@ An entire domain can be whitelisted for username administration by setting envio
 
 ### Systemd socket activation
 
-To use systemd socket activation add ```--systemd-socket``` flag. For more information see [this pull request](https://github.com/rickbergfalk/sqlpad/pull/185).
+To use systemd socket activation add ```--systemdSocket``` flag. For more information see [this pull request](https://github.com/rickbergfalk/sqlpad/pull/185).
diff --git a/docs/posts/installation-and-administration/index.html b/docs/posts/installation-and-administration/index.html
index ccf058c5..a106da76 100644
--- a/docs/posts/installation-and-administration/index.html
+++ b/docs/posts/installation-and-administration/index.html
@@ -80,32 +80,6 @@ Installation &amp; Administration &ndash; SQLPad - A web app for running SQL que
 
 <p><code>sqlpad --help</code></p>
 
-<h3 id="a-realistic-example">A Realistic Example:</h3>
-
-<p><code>sqlpad --dir c:/sqlpad/ --port 3000 --passphrase secret-encryption-phrase</code></p>
-
-<p>The <strong>dir</strong> argument specifies where to keep the sqlpad query/user/connection files. If not provided, SQLPad will put its files in the user&rsquo;s home directory under /sqlpad/db.</p>
-
-<p>The <strong>port</strong> argument specifies the port on which SQLPad should run. The default is port 80, but that may not be available.</p>
-
-<p>The <strong>passphrase</strong> argument is used to encrypt database connection usernames and passwords, and cookie encryption. If not provided, SQLPad will use the default to at least prevent usernames and passwords from being stored in plaintext.</p>
-
-<p>If a passphrase is ever changed or forgotten, you&rsquo;ll need to re-add the connection usernames and passwords to each database connection.</p>
-
-<p>If you ever want to save the arguments you are passing in so you don&rsquo;t have to remember them, you can save them by passing in the <code>--save</code> argument.</p>
-
-<p><code>sqlpad --dir ./sqlpad/ --port 3000 --passphrase secret-encryption-phrase --save</code></p>
-
-<p>Then the next time you can simply run&hellip;</p>
-
-<p><code>sqlpad</code></p>
-
-<p>&hellip;and Sqlpad will use directory ./sqlpad, on port 3000, with the proper encryption passphrase.</p>
-
-<p>These settings can be forgotten by running</p>
-
-<p><code>sqlpad --forget</code></p>
-
 <h2 id="administration">Administration</h2>
 
 <p>Once SQLPad is running, create an initial admin account by navigating to <a href="http://localhost/signup">http://localhost/signup</a>.</p>
@@ -196,7 +170,7 @@ For OAuth to be useful this usually involves the following:</p>
 
 <h3 id="systemd-socket-activation">Systemd socket activation</h3>
 
-<p>To use systemd socket activation add <code>--systemd-socket</code> flag. For more information see <a href="https://github.com/rickbergfalk/sqlpad/pull/185">this pull request</a>.</p>
+<p>To use systemd socket activation add <code>--systemdSocket</code> flag. For more information see <a href="https://github.com/rickbergfalk/sqlpad/pull/185">this pull request</a>.</p>
 
       </div>
   </div>
diff --git a/server/lib/cli-flow.js b/server/lib/cli-flow.js
index 849943ff..9e0a26c5 100644
--- a/server/lib/cli-flow.js
+++ b/server/lib/cli-flow.js
@@ -3,35 +3,26 @@ const argv = minimist(process.argv.slice(2));
 const packageJson = require('../package.json');
 const configItems = require('./config/configItems');
 
-const helpOptions = configItems.map(item => {
-  let lastFlag = '';
-  if (Array.isArray(item.cliFlag)) {
-    lastFlag = item.cliFlag[item.cliFlag.length - 1];
-  } else if (item.cliFlag) {
-    lastFlag = item.cliFlag;
-  }
-
-  return {
-    key: item.key,
-    flag: lastFlag,
-    description: item.description,
-    envVar: item.envVar
-  };
-});
+const keyLengths = configItems.map(item => item.key.length);
+const keyPadding = Math.max(...keyLengths) + 2;
 
 const helpText = `
 SQLPad version:  ${packageJson.version}
 
-Usage:  sqlpad [options]
+CLI examples: 
+
+  sqlpad --dbPath ../db --port 3010 --debug --baseUrl /sqlpad
+  node server.js --dbPath ../db --port 3010 --debug --baseUrl /sqlpad
+  node server.js --config path/to/file.json
+  node server.js --config path/to/file.ini
 
 Options:
 
-${helpOptions
-  .filter(option => Boolean(option.flag))
+${configItems
   .map(option => {
-    return `  --${option.flag}    ${option.description}\n`;
+    return `  --${option.key.padEnd(keyPadding)}${option.description}\n`;
   })
-  .join('\n')}`;
+  .join('')}`;
 
 // If version is requested show version then exit
 if (argv.v || argv.version) {
diff --git a/server/lib/config/configItems.js b/server/lib/config/configItems.js
index dd3025c0..e5a8929d 100644
--- a/server/lib/config/configItems.js
+++ b/server/lib/config/configItems.js
@@ -1,21 +1,18 @@
 const configItems = [
   {
     key: 'config',
-    cliFlag: 'config',
     envVar: 'SQLPAD_CONFIG',
     default: '',
     description: 'JSON/INI file to read for config'
   },
   {
     key: 'cookieSecret',
-    cliFlag: 'cookie-secret',
     envVar: 'SQLPAD_COOKIE_SECRET',
     default: 'secret-used-to-sign-cookies-please-set-and-make-strong',
     description: 'Secret used to sign cookies'
   },
   {
     key: 'sessionMinutes',
-    cliFlag: 'session-minutes',
     envVar: 'SQLPAD_SESSION_MINUTES',
     default: 60,
     description:
@@ -23,7 +20,6 @@ const configItems = [
   },
   {
     key: 'ip',
-    cliFlag: 'ip',
     envVar: 'SQLPAD_IP',
     default: '0.0.0.0',
     description:
@@ -31,28 +27,24 @@ const configItems = [
   },
   {
     key: 'port',
-    cliFlag: 'port',
     envVar: 'SQLPAD_PORT',
     default: 80,
     description: 'Port for SQLPad to listen on.'
   },
   {
     key: 'systemdSocket',
-    cliFlag: 'systemd-socket',
     envVar: 'SQLPAD_SYSTEMD_SOCKET',
     default: false,
     description: 'Acquire socket from systemd if available'
   },
   {
     key: 'httpsPort',
-    cliFlag: 'https-port',
     envVar: 'SQLPAD_HTTPS_PORT',
     default: 443,
     description: 'Port for SQLPad to listen on.'
   },
   {
     key: 'dbPath',
-    cliFlag: ['db', 'dbPath', 'dir'],
     envVar: 'SQLPAD_DB_PATH',
     default: '',
     description:
@@ -60,7 +52,6 @@ const configItems = [
   },
   {
     key: 'baseUrl',
-    cliFlag: 'base-url',
     envVar: 'SQLPAD_BASE_URL',
     default: '',
     description:
@@ -68,7 +59,6 @@ const configItems = [
   },
   {
     key: 'passphrase',
-    cliFlag: 'passphrase',
     envVar: 'SQLPAD_PASSPHRASE',
     default: "At least the sensitive bits won't be plain text?",
     description:
@@ -76,35 +66,30 @@ const configItems = [
   },
   {
     key: 'certPassphrase',
-    cliFlag: 'cert-passphrase',
     envVar: 'CERT_PASSPHRASE',
     default: '',
     description: 'Passphrase for your SSL certification file'
   },
   {
     key: 'keyPath',
-    cliFlag: ['key', 'key-path', 'key-dir'],
     envVar: 'KEY_PATH',
     default: '',
     description: 'Absolute path to where SSL certificate key is stored'
   },
   {
     key: 'certPath',
-    cliFlag: ['cert', 'cert-path', 'cert-dir'],
     envVar: 'CERT_PATH',
     default: '',
     description: 'Absolute path to where SSL certificate is stored'
   },
   {
     key: 'admin',
-    cliFlag: 'admin',
     envVar: 'SQLPAD_ADMIN',
     default: '',
     description: 'Email address to whitelist/give admin permissions to'
   },
   {
     key: 'debug',
-    cliFlag: 'debug',
     envVar: 'SQLPAD_DEBUG',
     default: false,
     description: 'Add a variety of logging to console while running SQLPad'
@@ -126,7 +111,6 @@ const configItems = [
   {
     key: 'publicUrl',
     envVar: 'PUBLIC_URL',
-    cliFlag: 'public-url',
     description:
       'Public URL used for OAuth setup and email links. Protocol expected. Example: https://mysqlpad.com',
     default: ''
@@ -175,7 +159,6 @@ const configItems = [
   {
     key: 'smtpFrom',
     envVar: 'SQLPAD_SMTP_FROM',
-    cliFlag: 'smtp-from',
     description:
       'From email address for SMTP. Required in order to send invitation emails.',
     default: ''
@@ -183,7 +166,6 @@ const configItems = [
   {
     key: 'smtpHost',
     envVar: 'SQLPAD_SMTP_HOST',
-    cliFlag: 'smtp-host',
     description:
       'Host address for SMTP. Required in order to send invitation emails.',
     default: ''
@@ -191,14 +173,12 @@ const configItems = [
   {
     key: 'smtpPort',
     envVar: 'SQLPAD_SMTP_PORT',
-    cliFlag: 'smtp-port',
     description: 'Port for SMTP. Required in order to send invitation emails.',
     default: ''
   },
   {
     key: 'smtpSecure',
     envVar: 'SQLPAD_SMTP_SECURE',
-    cliFlag: 'smtp-secure',
     options: [true, false],
     description: 'Toggle to use secure connection when using SMTP.',
     default: true
@@ -206,7 +186,6 @@ const configItems = [
   {
     key: 'smtpUser',
     envVar: 'SQLPAD_SMTP_USER',
-    cliFlag: 'smtp-user',
     description:
       'Username for SMTP. Required in order to send invitation emails.',
     default: ''
@@ -214,14 +193,12 @@ const configItems = [
   {
     key: 'smtpPassword',
     envVar: 'SQLPAD_SMTP_PASSWORD',
-    cliFlag: 'smtp-password',
     description: 'Password for SMTP.',
     default: ''
   },
   {
     key: 'whitelistedDomains',
     envVar: 'WHITELISTED_DOMAINS',
-    cliFlag: 'whitelisted-domains',
     description:
       'Allows pre-approval of email domains. Delimit multiple domains by empty space.',
     default: ''
@@ -229,7 +206,6 @@ const configItems = [
   {
     key: 'disableUpdateCheck',
     envVar: 'SQLPAD_DISABLE_UPDATE_CHECK',
-    cliFlag: 'disable-update-check',
     options: [true, false],
     description:
       'If disabled, SQLPad will no longer poll npmjs.com to see if an update is available.',
@@ -238,36 +214,30 @@ const configItems = [
   {
     key: 'samlEntryPoint',
     envVar: 'SAML_ENTRY_POINT',
-    cliFlag: 'saml-entry-point',
     description: 'SAML Entry point URL',
     default: ''
   },
   {
     key: 'samlIssuer',
     envVar: 'SAML_ISSUER',
-    cliFlag: 'saml-issuer',
     description: 'SAML Issuer',
     default: ''
   },
   {
     key: 'samlCallbackUrl',
     envVar: 'SAML_CALLBACK_URL',
-    cliFlag: 'saml-callback-url',
     description: 'SAML callback URL',
     default: ''
   },
   {
     key: 'samlCert',
     envVar: 'SAML_CERT',
-    cliFlag: 'saml-cert',
     description: 'SAML certificate in Base64',
     default: ''
   },
   {
-    interface: 'env',
     key: 'samlAuthContext',
     envVar: 'SAML_AUTH_CONTEXT',
-    cliFlag: 'saml-auth-context',
     description: 'SAML authentication context URL',
     default: ''
   }
diff --git a/server/lib/config/fromCli.js b/server/lib/config/fromCli.js
index 2acc7fe0..1968ed2a 100644
--- a/server/lib/config/fromCli.js
+++ b/server/lib/config/fromCli.js
@@ -6,19 +6,13 @@ const definitions = require('./configItems');
  * @returns {object} configMap
  */
 module.exports = function getCliConfig(argv) {
-  return definitions
-    .filter(definition => definition.hasOwnProperty('cliFlag'))
-    .reduce((confMap, definition) => {
-      const { key, cliFlag } = definition;
+  return definitions.reduce((confMap, definition) => {
+    const { key } = definition;
 
-      // cliFlag could have multiple flags defined
-      // TODO make consistent then deprecate old ones
-      const flags = Array.isArray(cliFlag) ? cliFlag : [cliFlag];
-      flags.forEach(flag => {
-        if (argv[flag] != null) {
-          confMap[key] = argv[flag];
-        }
-      });
-      return confMap;
-    }, {});
+    if (argv[key] != null) {
+      confMap[key] = argv[key];
+    }
+
+    return confMap;
+  }, {});
 };
diff --git a/server/lib/config/fromFile.js b/server/lib/config/fromFile.js
index 16ab2939..b6a50eec 100644
--- a/server/lib/config/fromFile.js
+++ b/server/lib/config/fromFile.js
@@ -32,19 +32,6 @@ function fromFile(configFilePath) {
       const configItem = configItems.find(item => item.key === key);
       if (!configItem) {
         let warningMessage = `Config key ${key} in file ${configFilePath} not recognized.`;
-
-        // Find the item it might be and give the user a hint
-        const maybeItem = configItems.find(item => {
-          if (Array.isArray(item.cliFlag)) {
-            return item.cliFlag.includes(key);
-          }
-          return item.cliFlag === key;
-        });
-        if (maybeItem) {
-          warningMessage += ` Did you mean ${maybeItem.key}?`;
-        } else {
-          warningMessage += ' It can likely be removed.';
-        }
         warnings.push(warningMessage);
       }
     });
diff --git a/server/package.json b/server/package.json
index 92526c0c..25e2d96a 100644
--- a/server/package.json
+++ b/server/package.json
@@ -28,7 +28,7 @@
   },
   "scripts": {
     "prepublishOnly": "cd .. && ./scripts/build.sh",
-    "start": "node-dev server.js --dir ../db --port 3010 --debug --base-url /sqlpad",
+    "start": "node-dev server.js --dbPath ../db --port 3010 --debug --baseUrl /sqlpad",
     "test": "rimraf ../dbtest && SQLPAD_DB_PATH='../dbtest' SQLPAD_TEST='true' mocha test --timeout 10000 --recursive --exit",
     "fixlint": "eslint --fix '**/*.js'",
     "lint": "eslint '**/*.js'"


Test patch:
diff --git a/server/test/lib/config.js b/server/test/lib/config.js
index 80174e0c..5df192c1 100644
--- a/server/test/lib/config.js
+++ b/server/test/lib/config.js
@@ -19,8 +19,8 @@ describe('config', function() {
 
   it('cli', function() {
     const conf = fromCli({
-      'key-path': 'key/path',
-      cert: 'cert/path',
+      keyPath: 'key/path',
+      certPath: 'cert/path',
       admin: 'admin@email.com'
     });
     assert.equal(conf.keyPath, 'key/path', 'keyPath');