v0.0.1
[henge/kiak.git] / opts.js
diff --git a/opts.js b/opts.js
new file mode 100644 (file)
index 0000000..e97d84e
--- /dev/null
+++ b/opts.js
@@ -0,0 +1,108 @@
+/**
+ * @file      Establishes runtime options from args and config files
+ * @author    Ken Grimes
+ * @version   0.0.1
+ * @license   AGPL-3.0
+ * @copyright jk software 2017
+ */
+const fs = require('fs')
+const path = require('path')
+
+/**
+ * @summary Parse arguments with minimist
+ */
+exports = require('minimist')(process.argv.slice(2), {
+  string:  [ 'config', 'client-js', 'host-js', 'ca-cert', 'ca-key',
+            'port', 'index', 'bind', 'electron', 'dedicated'
+          ],
+  boolean: [ 'no-tls', 'legacy-socket' ],
+  alias:   { c: 'config',
+            j: 'client-js',
+            J: 'host-js',
+            T: 'no-tls',
+            C: 'ca-cert',
+            K: 'ca-key',
+            p: 'port',
+            i: 'index',
+            b: 'bind',
+            e: 'electron',
+            d: 'dedicated'
+          },
+  stopEarly: true,
+  unknown: (opt) => {
+    console.log('Unknown operator: ' + opt)
+    console.log(process.argv.join(' '))
+    console.log(fs.readFileSync('./usage'))
+    process.exit()
+  }
+})
+
+/**
+ * @summary Defaults
+ */
+exports['defaults'] = {
+  config:      '/etc/strapp.conf:~/.strapp/strapp.conf:./strapp.conf',
+  'client-js': './client.js',
+  'host-js':   './host.js',
+  tls:         true,
+  'ca-cert':   '../certs/cert.pem',
+  'ca-key':    '../certs/key.pem',
+  port:        2443,
+  index:       './www/index.html',
+  bind:        'www:./www',
+  electron:    undefined,
+  dedicated:   undefined,
+  'legacy-socket': false
+}
+
+exports = Object.assign({}, exports['defaults'], exports)
+
+/**
+ * @summary Parse config files
+ */
+exports['conf'] = {}
+exports['config'].split(':').forEach((fileName) => {
+  let filePath = path.resolve(fileName)
+  if (fs.existsSync(filePath)){
+    let lineNo = 0;
+    String(fs.readFileSync(path.resolve(fileName))).split('\n').forEach((line) => {
+      lineNo++
+      /* Skip comments */
+      if (!line.match(/[\s]*#/)) {
+       let kv = line.replace(/#.*/g,'').replace(/\s/g,'').split('=')
+       if (kv.length == 2 && kv[0] in exports['defaults']) {
+         /* Multiple "bind=..." lines in are additive */
+         if (kv[0] === 'bind' && 'bind' in exports['conf']) {
+             kv[1] = exports['conf']['bind'] + ',' + kv[1]
+         }
+         exports['conf'][kv[0]] = kv[1]
+       }
+       else
+         console.log(`WARN: Bad option ${line} in ${fileName}:${lineNo}`)
+      }
+    })
+  }
+  else if (exports['config'] !== exports['defaults']['config'])
+    console.log(`WARN: opt '-c${exports['config']}', ${fileName} inaccessible`)
+})
+
+exports = Object.assign({}, exports['defaults'], exports['conf'], exports)
+
+/**
+ * @summary Parse bindings
+ */
+exports['bindings'] = {}
+exports['bind'].replace(/\s/g,'').split(',').forEach((kvp) => {
+  let kv = kvp.split(':')
+  kv[1] = path.resolve(kv[1])
+  if (fs.existsSync(kv[1])) {
+    if (kv.length == 2 && /^[-_.A-Za-z0-9]/g.test(kv[0]))
+      exports['bindings'][kv[0]] = kv[1]
+    else
+      console.log(`WARN: Invalid binding: ${kvp}`)
+  }
+  else
+    console.log(`WARN: Binding not made, directory ${kvp} inaccessible`)
+})
+
+module.exports = exports