Joey Mazzarelli avatar Joey Mazzarelli committed e84e7c9

initial commit

Comments (0)

Files changed (6)

+Author   : Joey Mazzarelli
+Email    : mazzarelli@gmail.com
+Homepage : http://joey.mazzarelli.com
+Source   : http://bitbucket.org/mazzarell/js-opts/
+License  : Simplified BSD License
+
+Copyright 2010 Joey Mazzarelli. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY JOEY MAZZARELLI 'AS IS' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL JOEY MAZZARELLI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those
+of the authors and should not be interpreted as representing official policies,
+either expressed or implied, of Joey Mazzarelli.
+
+Version:
+1.0
+
+Installation:
+Just copy opts.js to your node.js project and import it with the require
+function. See included files for an example.
+
+Bugs:
+Please report bugs tohttp://bitbucket.org/mazzarelli/js-opts/issues/
+
+/**
+ * Simple example with one optional parameter, including the help option.
+ *
+ * Examples:
+ *   $ node example1.js
+ *   
+ *   Example 1
+ *   $ node example1.js -v
+ *   > v1.0
+ *
+ *   $ node example1.js --version
+ *   > v1.0
+ *
+ *   $ node example1.js -version
+ *   > Unknown option: -version
+ *
+ *   $ node example1.js --help
+ *   > Show version and exit
+ *         -v, --version
+ *     Show this help message
+ *         --help
+ */
+
+var opts = require('./opts')
+  , puts = require('sys').puts;
+
+var options = [
+  { short       : 'v'
+  , long        : 'version'
+  , description : 'Show version and exit'
+  , callback    : function () { puts('v1.0'); process.exit(1); }
+  }
+];
+
+opts.parse(options, true);
+puts('Example 1');
+process.exit(0);
+
+
+/**
+ * More complex example.
+ *
+ * Run:
+ *   node example2.js --help
+ * and play with the options to see the behavior.
+ *
+ * This example shows different ways of using the library. It is deliberately 
+ * inconsistent. Choose the style that suits you best.
+ */
+
+var opts = require('./opts')
+  , puts = require('sys').puts
+  , host = 'localhost'; // default host value
+
+var options = [
+  { short       : 'v'
+  , long        : 'version'
+  , description : 'Show version and exit'
+  , callback    : function () { puts('v1.0'); process.exit(1); }
+  },
+  { short       : 'l'
+  , long        : 'list'
+  , description : 'List all files'
+  },
+  { short       : 'f'
+  , long        : 'file'
+  , description : 'Load a file'
+  , value       : true
+  , required    : true
+  },
+  { short       : 'd'
+  , long        : 'debug'
+  , description : 'Set a debug level'
+  , value       : true
+  },
+  { short       : 'h'
+  , long        : 'host'
+  , description : 'The hostname to connect to'
+  , value       : true
+  , callback    : function (value) { host = value; } // override host value
+  },
+  { short       : 'p'
+  , long        : 'port'
+  , description : 'The port to connect to'
+  , value       : true
+  },
+];
+
+opts.parse(options, true);
+
+var port  = opts.get('port') || 8000 // default port value
+  , debug = opts.get('d') || 'info'  // default debug value
+  , file  = opts.get('f')
+  , list  = opts.get('list');
+
+var arg1 = opts.args()[0]
+  , arg2 = opts.args()[1];
+
+
+if (list) puts('List arg was set');
+if (file) puts('File arg was set: ' + file);
+puts('Debug level is: ' + debug);
+puts('Host is: ' + host);
+puts('Port is: ' + port);
+
+if (arg1) puts('Extra arg 1: ' + arg1);
+if (arg2) puts('Extra arg 2: ' + arg2);
+
+process.exit(0);
+
+/**
+ * Simple example that is broken by design (conflicting options)
+ *
+ * Examples:
+ *   $ node example3.js
+ *   > Conflicting flags: -v
+ */
+
+var opts = require('./opts');
+
+var options = [
+  { short       : 'v'
+  , description : 'Show version and exit'
+  },
+  { short       : 'v'
+  , description : 'Be verbose'
+  },
+];
+
+opts.parse(options);
+puts('Example 3');
+process.exit(0);
+
+
+/***************************************************************************
+Author   : Joey Mazzarelli
+Email    : mazzarelli@gmail.com
+Homepage : http://joey.mazzarelli.com
+Source   : http://bitbucket.org/mazzarell/js-opts/
+License  : Simplified BSD License
+Version  : 1.0
+
+Copyright 2010 Joey Mazzarelli. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY JOEY MAZZARELLI 'AS IS' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL JOEY MAZZARELLI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those
+of the authors and should not be interpreted as representing official policies,
+either expressed or implied, of Joey Mazzarelli.
+***************************************************************************/
+
+var print       = require('sys').puts
+  , values      = {}
+  , args        = []
+  , errors      = []
+  , descriptors = [];
+
+
+/**
+ * Parse the command line options
+ * @param array options Options to parse
+ *
+ * Each option in the array can have the following fields. None are required, 
+ * but you should at least provide a short or long name.
+ *   {
+ *     short       : 'l',
+ *     long        : 'list',
+ *     description : 'Show a list',
+ *     value       : false,
+ *     required    : true,
+ *     callback    : function (value) { ... }
+ *   }
+ *
+ * You can add an automatically generated help message by passing
+ * a second parameter of <true> or by including the option;
+ *   {
+ *     long        : 'help',
+ *     description : 'Show this help message',
+ *     callback    : require('./opts').help,
+ *   }
+ */
+exports.parse = function (options, help) {
+
+  if (help) {
+    options.push({ long        : 'help'
+                 , description : 'Show this help message'
+                 , callback    : exports.help
+                 });
+  }
+  descriptors = options;
+
+  var opts = {};
+  for (var i=0; i<options.length; i++) {
+    if (options[i].short) {
+      if (!opts['-' + options[i].short]) {
+        opts['-' + options[i].short] = options[i];
+      } else {
+        print('Conflicting flags: -' + options[i].short);
+        process.exit(1);
+      }
+    }
+    if (options[i].long) {
+      if (!opts['--' + options[i].long]) {
+        opts['--' + options[i].long] = options[i];
+      } else {
+        print('Conflicting flags: --' + options[i].long);
+        process.exit(1);
+      }
+    }
+  }
+
+  for (var i=2; i<process.argv.length; i++) {
+    var inp = process.argv[i];
+    if (opts[inp]) {
+      // found a match, process it.
+      var opt = opts[inp];
+      if (!opt.value) {
+        if (opt.callback) opt.callback(true);
+        if (opt.short) values[opt.short] = true;
+        if (opt.long) values[opt.long] = true;
+      } else {
+        var next = process.argv[i+1];
+        if (!next || opts[next]) {
+          var flag = opt.short || opt.long;
+          errors.push('Missing value for argument: ' + flag);
+          if (opt.short) values[opt.short] = true;
+          if (opt.long) values[opt.long] = true;
+        } else {
+          if (opt.callback) opt.callback(next);
+          if (opt.short) values[opt.short] = next;
+          if (opt.long) values[opt.long] = next;
+          i++;
+        }
+      }
+    } else {
+      // No match. If it starts with a dash, show an error. Otherwise
+      // add it to the extra args.
+      if (inp[0] == '-') {
+        print('Unknown option: ' + inp);
+        if (opts['--help']) print('Try --help');
+        process.exit(1);
+      } else {
+        args.push(inp);
+      }
+    }
+  }
+  for (var i=0; i<options.length; i++) {
+    var flag = options[i].short || options[i].long;
+    if (options[i].required && !exports.get(flag)) {
+      errors.push('Missing required argument: ' + flag);
+    }
+  }
+  if (errors.length) {
+    for (var i=0; i<errors.length; i++) print(errors[i]);
+    process.exit(1);
+  }
+};
+
+/**
+ * Get the value of an option. Can be the short or long option
+ * @return string
+ */
+exports.get = function (opt) {
+  return values[opt] || values['-' + opt] || values['--' + opt];
+};
+
+/**
+ * Get unknown args. Could have special meaning to client
+ */
+exports.args = function () {
+  return args;
+};
+
+exports.help = function () {
+  for (var i=0; i<descriptors.length; i++) {
+    var opt = descriptors[i];
+    var line;
+    if (opt.description) print(opt.description);
+    if (opt.short && !opt.long) line = '-' + opt.short;
+    else if (opt.long && !opt.short) line = '--' + opt.long;
+    else line = '-' + opt.short + ', --' + opt.long;
+    if (opt.value) line += ' <value>';
+    if (opt.required) line += ' (required)';
+    print('    ' + line);
+  }
+  process.exit(1);
+};
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.