Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

update jshint, add production node_modules/

Recent JSHint releases need the production node modules
listed in the jshint package.json file.
  • Loading branch information...
commit 6a7676af5d1160f0bc5e33922c31a01cda25028f 1 parent c33f9a3
@stepheneb stepheneb authored
Showing with 20,479 additions and 0 deletions.
  1. +1 −0  Support/node_modules/.bin/shjs
  2. +196 −0 Support/node_modules/cli/README.md
  3. +1,133 −0 Support/node_modules/cli/cli.js
  4. +17 −0 Support/node_modules/cli/examples/cat.js
  5. +16 −0 Support/node_modules/cli/examples/command.js
  6. +54 −0 Support/node_modules/cli/examples/echo.js
  7. +6 −0 Support/node_modules/cli/examples/glob.js
  8. +20 −0 Support/node_modules/cli/examples/long_desc.js
  9. +11 −0 Support/node_modules/cli/examples/progress.js
  10. +18 −0 Support/node_modules/cli/examples/sort.js
  11. +9 −0 Support/node_modules/cli/examples/spinner.js
  12. +27 −0 Support/node_modules/cli/examples/static.coffee
  13. +25 −0 Support/node_modules/cli/examples/static.js
  14. +1 −0  Support/node_modules/cli/index.js
  15. +2 −0  Support/node_modules/cli/node_modules/glob/.npmignore
  16. +3 −0  Support/node_modules/cli/node_modules/glob/.travis.yml
  17. +27 −0 Support/node_modules/cli/node_modules/glob/LICENSE
  18. +250 −0 Support/node_modules/cli/node_modules/glob/README.md
  19. +9 −0 Support/node_modules/cli/node_modules/glob/examples/g.js
  20. +9 −0 Support/node_modules/cli/node_modules/glob/examples/usr-local.js
  21. +675 −0 Support/node_modules/cli/node_modules/glob/glob.js
  22. +16 −0 Support/node_modules/cli/node_modules/glob/node_modules/inherits/LICENSE
  23. +42 −0 Support/node_modules/cli/node_modules/glob/node_modules/inherits/README.md
  24. +1 −0  Support/node_modules/cli/node_modules/glob/node_modules/inherits/inherits.js
  25. +23 −0 Support/node_modules/cli/node_modules/glob/node_modules/inherits/inherits_browser.js
  26. +32 −0 Support/node_modules/cli/node_modules/glob/node_modules/inherits/package.json
  27. +25 −0 Support/node_modules/cli/node_modules/glob/node_modules/inherits/test.js
  28. +38 −0 Support/node_modules/cli/node_modules/glob/package.json
  29. +176 −0 Support/node_modules/cli/node_modules/glob/test/00-setup.js
  30. +63 −0 Support/node_modules/cli/node_modules/glob/test/bash-comparison.js
  31. +349 −0 Support/node_modules/cli/node_modules/glob/test/bash-results.json
  32. +55 −0 Support/node_modules/cli/node_modules/glob/test/cwd-test.js
  33. +19 −0 Support/node_modules/cli/node_modules/glob/test/globstar-match.js
  34. +74 −0 Support/node_modules/cli/node_modules/glob/test/mark.js
  35. +113 −0 Support/node_modules/cli/node_modules/glob/test/nocase-nomagic.js
  36. +73 −0 Support/node_modules/cli/node_modules/glob/test/pause-resume.js
  37. +39 −0 Support/node_modules/cli/node_modules/glob/test/root-nomount.js
  38. +46 −0 Support/node_modules/cli/node_modules/glob/test/root.js
  39. +32 −0 Support/node_modules/cli/node_modules/glob/test/stat.js
  40. +11 −0 Support/node_modules/cli/node_modules/glob/test/zz-cleanup.js
  41. +53 −0 Support/node_modules/cli/package.json
  42. +14 −0 Support/node_modules/console-browserify/.npmignore
  43. +14 −0 Support/node_modules/console-browserify/.testem.json
  44. +4 −0 Support/node_modules/console-browserify/.travis.yml
  45. +19 −0 Support/node_modules/console-browserify/LICENCE
  46. +32 −0 Support/node_modules/console-browserify/README.md
  47. +85 −0 Support/node_modules/console-browserify/index.js
  48. +76 −0 Support/node_modules/console-browserify/package.json
  49. +67 −0 Support/node_modules/console-browserify/test/index.js
  50. +12 −0 Support/node_modules/console-browserify/test/static/index.html
  51. +53 −0 Support/node_modules/console-browserify/test/static/test-adapter.js
  52. +23 −0 Support/node_modules/minimatch/LICENSE
  53. +218 −0 Support/node_modules/minimatch/README.md
  54. +1,079 −0 Support/node_modules/minimatch/minimatch.js
  55. +1 −0  Support/node_modules/minimatch/node_modules/lru-cache/.npmignore
  56. +8 −0 Support/node_modules/minimatch/node_modules/lru-cache/AUTHORS
  57. +23 −0 Support/node_modules/minimatch/node_modules/lru-cache/LICENSE
  58. +97 −0 Support/node_modules/minimatch/node_modules/lru-cache/README.md
  59. +25 −0 Support/node_modules/minimatch/node_modules/lru-cache/bench.js
  60. +263 −0 Support/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
  61. +62 −0 Support/node_modules/minimatch/node_modules/lru-cache/package.json
  62. +329 −0 Support/node_modules/minimatch/node_modules/lru-cache/test/basic.js
  63. +52 −0 Support/node_modules/minimatch/node_modules/lru-cache/test/foreach.js
  64. +50 −0 Support/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js
  65. +27 −0 Support/node_modules/minimatch/node_modules/sigmund/LICENSE
  66. +53 −0 Support/node_modules/minimatch/node_modules/sigmund/README.md
  67. +283 −0 Support/node_modules/minimatch/node_modules/sigmund/bench.js
  68. +41 −0 Support/node_modules/minimatch/node_modules/sigmund/package.json
  69. +39 −0 Support/node_modules/minimatch/node_modules/sigmund/sigmund.js
  70. +24 −0 Support/node_modules/minimatch/node_modules/sigmund/test/basic.js
  71. +39 −0 Support/node_modules/minimatch/package.json
  72. +399 −0 Support/node_modules/minimatch/test/basic.js
  73. +33 −0 Support/node_modules/minimatch/test/brace-expand.js
  74. +14 −0 Support/node_modules/minimatch/test/caching.js
  75. +274 −0 Support/node_modules/minimatch/test/defaults.js
  76. +6 −0 Support/node_modules/shelljs/.documentup.json
  77. +1 −0  Support/node_modules/shelljs/.npmignore
  78. +5 −0 Support/node_modules/shelljs/.travis.yml
  79. +26 −0 Support/node_modules/shelljs/LICENSE
  80. +513 −0 Support/node_modules/shelljs/README.md
  81. +51 −0 Support/node_modules/shelljs/bin/shjs
  82. +3 −0  Support/node_modules/shelljs/global.js
  83. +4 −0 Support/node_modules/shelljs/jshint.json
  84. +48 −0 Support/node_modules/shelljs/make.js
  85. +44 −0 Support/node_modules/shelljs/package.json
  86. +15 −0 Support/node_modules/shelljs/scripts/docs.js
  87. +50 −0 Support/node_modules/shelljs/scripts/run-tests.js
  88. +1,901 −0 Support/node_modules/shelljs/shell.js
  89. +2 −0  Support/node_modules/shelljs/test/.npmignore
  90. +57 −0 Support/node_modules/shelljs/test/cat.js
  91. +64 −0 Support/node_modules/shelljs/test/cd.js
  92. +81 −0 Support/node_modules/shelljs/test/chmod.js
  93. +50 −0 Support/node_modules/shelljs/test/config.js
  94. +143 −0 Support/node_modules/shelljs/test/cp.js
  95. +37 −0 Support/node_modules/shelljs/test/dirs.js
  96. +50 −0 Support/node_modules/shelljs/test/echo.js
  97. +19 −0 Support/node_modules/shelljs/test/env.js
  98. +109 −0 Support/node_modules/shelljs/test/exec.js
  99. +56 −0 Support/node_modules/shelljs/test/find.js
  100. +59 −0 Support/node_modules/shelljs/test/grep.js
  101. +202 −0 Support/node_modules/shelljs/test/ls.js
  102. +20 −0 Support/node_modules/shelljs/test/make.js
  103. +79 −0 Support/node_modules/shelljs/test/mkdir.js
  104. +130 −0 Support/node_modules/shelljs/test/mv.js
  105. +118 −0 Support/node_modules/shelljs/test/popd.js
  106. +228 −0 Support/node_modules/shelljs/test/pushd.js
  107. +28 −0 Support/node_modules/shelljs/test/pwd.js
  108. +11 −0 Support/node_modules/shelljs/test/resources/a.txt
  109. 0  Support/node_modules/shelljs/test/resources/chmod/a/b/c/.npmignore
  110. 0  Support/node_modules/shelljs/test/resources/chmod/b/a/b/.npmignore
  111. 0  Support/node_modules/shelljs/test/resources/chmod/c/a/b/.npmignore
  112. +2 −0  Support/node_modules/shelljs/test/resources/chmod/file1
  113. +1 −0  Support/node_modules/shelljs/test/resources/cp/a
  114. +1 −0  Support/node_modules/shelljs/test/resources/cp/b
  115. +1 −0  Support/node_modules/shelljs/test/resources/cp/dir_a/z
  116. +1 −0  Support/node_modules/shelljs/test/resources/cp/dir_b/dir_b_a/dir_b_a_a/z
  117. +2 −0  Support/node_modules/shelljs/test/resources/external/node_script.js
  118. +1 −0  Support/node_modules/shelljs/test/resources/file1
  119. +1 −0  Support/node_modules/shelljs/test/resources/file1.js
  120. +1 −0  Support/node_modules/shelljs/test/resources/file1.txt
  121. +1 −0  Support/node_modules/shelljs/test/resources/file2
  122. +1 −0  Support/node_modules/shelljs/test/resources/file2.js
  123. +1 −0  Support/node_modules/shelljs/test/resources/file2.txt
  124. +1 −0  Support/node_modules/shelljs/test/resources/find/.hidden
  125. +1 −0  Support/node_modules/shelljs/test/resources/find/a
  126. +1 −0  Support/node_modules/shelljs/test/resources/find/b
  127. +1 −0  Support/node_modules/shelljs/test/resources/find/dir1/a_dir1
  128. +1 −0  Support/node_modules/shelljs/test/resources/find/dir1/dir11/a_dir11
  129. +1 −0  Support/node_modules/shelljs/test/resources/find/dir2/a_dir1
  130. +1 −0  Support/node_modules/shelljs/test/resources/issue44/main.js
  131. +1 −0  Support/node_modules/shelljs/test/resources/ls/.hidden_dir/nada
  132. +1 −0  Support/node_modules/shelljs/test/resources/ls/.hidden_file
  133. +1 −0  Support/node_modules/shelljs/test/resources/ls/a_dir/.hidden_dir/nada
  134. +1 −0  Support/node_modules/shelljs/test/resources/ls/a_dir/b_dir/z
  135. +1 −0  Support/node_modules/shelljs/test/resources/ls/a_dir/nada
  136. +1 −0  Support/node_modules/shelljs/test/resources/ls/file1
  137. +1 −0  Support/node_modules/shelljs/test/resources/ls/file1.js
  138. +1 −0  Support/node_modules/shelljs/test/resources/ls/file2
  139. +1 −0  Support/node_modules/shelljs/test/resources/ls/file2.js
  140. +1 −0  Support/node_modules/shelljs/test/resources/ls/filename(with)[chars$]^that.must+be-escaped
  141. +1 −0  Support/node_modules/shelljs/test/resources/pushd/a/dummy
  142. +1 −0  Support/node_modules/shelljs/test/resources/pushd/b/c/dummy
  143. +183 −0 Support/node_modules/shelljs/test/rm.js
  144. +58 −0 Support/node_modules/shelljs/test/sed.js
  145. +27 −0 Support/node_modules/shelljs/test/tempdir.js
  146. +91 −0 Support/node_modules/shelljs/test/test.js
  147. +39 −0 Support/node_modules/shelljs/test/to.js
  148. +38 −0 Support/node_modules/shelljs/test/which.js
  149. +4 −0 Support/node_modules/underscore/.npmignore
  150. +5 −0 Support/node_modules/underscore/.travis.yml
  151. +1 −0  Support/node_modules/underscore/CNAME
  152. +9 −0 Support/node_modules/underscore/CONTRIBUTING.md
  153. +22 −0 Support/node_modules/underscore/LICENSE
  154. +19 −0 Support/node_modules/underscore/README.md
  155. BIN  Support/node_modules/underscore/favicon.ico
  156. +2,467 −0 Support/node_modules/underscore/index.html
  157. +1 −0  Support/node_modules/underscore/index.js
  158. +35 −0 Support/node_modules/underscore/package.json
  159. +1 −0  Support/node_modules/underscore/underscore-min.js
  160. +1,226 −0 Support/node_modules/underscore/underscore.js
  161. +78 −0 Support/package.json
  162. +4,311 −0 jshint.js
View
1  Support/node_modules/.bin/shjs
View
196 Support/node_modules/cli/README.md
@@ -0,0 +1,196 @@
+**cli is a toolkit for rapidly building command line apps - it includes:**
+
+- Full featured opts/args parser
+- Plugin support for adding common options and switches
+- Helper methods for working with input/output and spawning child processes
+- Output colored/styled messages, [progress bars](https://github.com/chriso/cli/blob/master/examples/progress.js) or [spinners](https://github.com/chriso/cli/blob/master/examples/spinner.js)
+- Command [auto-completion](https://github.com/chriso/cli/blob/master/examples/command.js) and [glob support](https://github.com/chriso/cli/blob/master/examples/glob.js)
+
+Install using `npm install cli` or just bundle [cli.js](https://github.com/chriso/cli/raw/master/cli-min.js) with your app.
+
+## Example apps
+
+### sort.js
+
+```javascript
+#!/usr/bin/env node
+require('cli').withStdinLines(function(lines, newline) {
+ this.output(lines.sort().join(newline));
+});
+```
+
+Try it out
+
+```bash
+$ ./sort.js < input.txt
+```
+
+Let's add support for an `-n` switch to use a numeric sort, and a `-r` switch to reverse output - only 5 extra lines of code (!)
+
+```javascript
+var cli = require('cli'), options = cli.parse();
+
+cli.withStdinLines(function(lines, newline) {
+ lines.sort(!options.n ? null : function(a, b) {
+ return parseInt(a) > parseInt(b);
+ });
+ if (options.r) lines.reverse();
+ this.output(lines.join(newline));
+});
+```
+
+### static.js
+
+Let's create a static file server with daemon support to see the opts parser + plugins in use - note: this requires `npm install creationix daemon`
+
+```javascript
+var cli = require('cli').enable('daemon', 'status'); //Enable 2 plugins
+
+cli.parse({
+ log: ['l', 'Enable logging'],
+ port: ['p', 'Listen on this port', 'number', 8080],
+ serve: [false, 'Serve static files from PATH', 'path', './public']
+});
+
+cli.main(function(args, options) {
+ var server, middleware = [];
+
+ if (options.log) {
+ this.debug('Enabling logging');
+ middleware.push(require('creationix/log')());
+ }
+
+ this.debug('Serving files from ' + options.serve);
+ middleware.push(require('creationix/static')('/', options.serve, 'index.html'));
+
+ server = this.createServer(middleware).listen(options.port);
+
+ this.ok('Listening on port ' + options.port);
+});
+```
+
+To output usage information
+
+```bash
+$ ./static.js --help
+```
+
+To create a daemon that serves files from */tmp*, run
+
+```bash
+$ ./static.js -ld --serve=/tmp
+```
+
+For more examples, see [./examples](https://github.com/chriso/cli/tree/master/examples)
+
+## Helper methods
+
+cli has methods that collect stdin (newline is autodetected as \n or \r\n)
+
+```javascript
+cli.withStdin(callback); //callback receives stdin as a string
+cli.withStdinLines(callback); //callback receives stdin split into an array of lines (lines, newline)
+```
+
+cli also has a lower level method for working with input line by line (see [./examples/cat.js](https://github.com/chriso/cli/blob/master/examples/cat.js) for an example).
+
+```javascript
+cli.withInput(file, function (line, newline, eof) {
+ if (!eof) {
+ this.output(line + newline);
+ }
+});
+```
+
+*Note: `file` can be omitted if you want to work with stdin*
+
+To output a progress bar, call
+
+```javascript
+cli.progress(progress); //Where 0 <= progress <= 1
+```
+
+To spawn a child process, use
+
+```javascript
+cli.exec(cmd, callback); //callback receives the output of the process (split into lines)
+```
+
+cli also comes bundled with kof's [node-natives](https://github.com/kof/node-natives) (access with cli.native) and creationix' [stack](https://github.com/creationix/stack) (access with cli.createServer)
+
+## Plugins
+
+Plugins are a way of adding common opts and can be enabled using
+
+```javascript
+cli.enable(plugin1, [plugin2, ...]); //To disable, use the equivalent disable() method
+```
+
+**help** - *enabled by default*
+
+Adds `-h,--help` to output auto-generated usage information
+
+**version**
+
+Adds `-v,--version` to output version information for the app. cli will attempt to locate and parse a nearby *package.json*
+
+To set your own app name and version, use `cli.setApp(app_name, version)`
+
+**status**
+
+Adds options to show/hide the stylized status messages that are output to the console when using one of these methods
+
+```javascript
+cli.debug(msg); //Only shown when using --debug
+cli.error(msg);
+cli.fatal(msg); //Exits the process after outputting msg
+cli.info(msg);
+cli.ok(msg);
+```
+
+`-k,--no-color` will omit ANSI color escapes from the output
+
+**glob** - *requires* `npm install glob`
+
+Enables glob matching of arguments
+
+**daemon** - *requires* `npm install daemon`
+
+Adds `-d,--daemon ARG` for daemonizing the process and controlling the resulting daemon
+
+`ARG` can be either start (default), stop, restart, pid (outputs the daemon's pid if it's running), or log (output the daemon's stdout+stderr)
+
+**timeout**
+
+Adds `-t,--timeout N` to exit the process after N seconds with an error
+
+**catchall**
+
+Adds `-c,--catch` to catch and output uncaughtExceptions and resume execution
+
+*Note: Plugins are automatically disabled if an option or switch of the same name is already defined*
+
+## LICENSE
+
+(MIT license)
+
+Copyright (c) 2010 Chris O'Hara <cohara87@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
1,133 Support/node_modules/cli/cli.js
@@ -0,0 +1,1133 @@
+/**
+ * Copyright (c) 2010 Chris O'Hara <cohara87@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+ //Note: cli includes kof/node-natives and creationix/stack. I couldn't find
+ //license information for either - contact me if you want your license added
+
+var cli = exports,
+ argv, curr_opt, curr_val, full_opt, is_long,
+ short_tags = [], opt_list, parsed = {},
+ usage, argv_parsed, command_list, commands,
+ daemon, daemon_arg, no_color, show_debug;
+
+cli.app = null;
+cli.version = null;
+cli.argv = [];
+cli.argc = 0;
+
+cli.options = {};
+cli.args = [];
+cli.command;
+
+cli.width = 70;
+cli.option_width = 25;
+
+/**
+ * Bind kof's node-natives (https://github.com/kof/node-natives) to `cli.native`
+ *
+ * Rather than requiring node natives (e.g. var fs = require('fs')), all
+ * native modules can be accessed like `cli.native.fs`
+ */
+cli.native = {};
+var define_native = function (module) {
+ Object.defineProperty(cli.native, module, {
+ enumerable: true,
+ configurable: true,
+ get: function() {
+ delete cli.native[module];
+ return cli.native[module] = require(module);
+ }
+ });
+};
+var natives = process.binding('natives');
+for (var module in natives) {
+ define_native(module);
+}
+
+cli.output = cli.native.util.print;
+cli.exit = process.exit;
+
+/**
+ * Define plugins. Plugins can be enabled and disabled by calling:
+ *
+ * `cli.enable(plugin1, [plugin2, ...])`
+ * `cli.disable(plugin1, [plugin2, ...])`
+ *
+ * Methods are chainable - `cli.enable(plugin).disable(plugin2)`.
+ *
+ * The 'help' plugin is enabled by default.
+ */
+var enable = {
+ help: true, //Adds -h, --help
+ version: false, //Adds -v,--version => gets version by parsing a nearby package.json
+ daemon: false, //Adds -d,--daemon [ARG] => (see cli.daemon() below)
+ status: false, //Adds -k,--no-color & --debug => display plain status messages /display debug messages
+ timeout: false, //Adds -t,--timeout N => timeout the process after N seconds
+ catchall: false, //Adds -c,--catch => catch and output uncaughtExceptions
+ glob: false //Adds glob matching => use cli.glob(arg)
+}
+cli.enable = function (/*plugins*/) {
+ Array.prototype.slice.call(arguments).forEach(function (plugin) {
+ switch (plugin) {
+ case 'daemon':
+ try {
+ daemon = require('daemon');
+ if (typeof daemon.daemonize !== 'function') {
+ throw 'Invalid module';
+ }
+ } catch (e) {
+ cli.fatal('daemon.node not installed. Please run `npm install daemon`');
+ }
+ break;
+ case 'catchall':
+ process.on('uncaughtException', function (err) {
+ cli.error('Uncaught exception: ' + (err.msg || err));
+ });
+ break;
+ case 'help': case 'version': case 'status':
+ case 'autocomplete': case 'timeout':
+ //Just add switches.
+ break;
+ case 'glob':
+ cli.glob = require('glob');
+ break;
+ default:
+ cli.fatal('Unknown plugin "' + plugin + '"');
+ break;
+ }
+ enable[plugin] = true;
+ });
+ return cli;
+}
+cli.disable = function (/*plugins*/) {
+ Array.prototype.slice.call(arguments).forEach(function (plugin) {
+ if (enable[plugin]) {
+ enable[plugin] = false;
+ }
+ });
+ return cli;
+}
+
+/**
+ * Sets argv (default is process.argv).
+ *
+ * @param {Array|String} argv
+ * @param {Boolean} keep_arg0 (optional - default is false)
+ * @api public
+ */
+cli.setArgv = function (arr, keep_arg0) {
+ if (typeof arr == 'string') {
+ arr = arr.split(' ');
+ } else {
+ arr = arr.slice();
+ }
+ cli.app = arr.shift();
+ //Strip off argv[0] if it's a node binary
+ if (!keep_arg0 && ('node' === cli.native.path.basename(cli.app)
+ || process.execPath === cli.app)) {
+ cli.app = arr.shift();
+ }
+ cli.app = cli.native.path.basename(cli.app);
+ argv_parsed = false;
+ cli.args = cli.argv = argv = arr;
+ cli.argc = argv.length;
+ cli.options = {};
+ cli.command = null;
+};
+cli.setArgv(process.argv);
+
+/**
+ * Returns the next opt, or false if no opts are found.
+ *
+ * @return {String} opt
+ * @api public
+ */
+cli.next = function () {
+ if (!argv_parsed) {
+ cli.args = [];
+ argv_parsed = true;
+ }
+
+ curr_val = null;
+
+ //If we're currently in a group of short opts (e.g. -abc), return the next opt
+ if (short_tags.length) {
+ curr_opt = short_tags.shift();
+ full_opt = '-' + curr_opt;
+ return curr_opt;
+ }
+
+ if (!argv.length) {
+ return false;
+ }
+
+ curr_opt = argv.shift();
+
+ //If an escape sequence is found (- or --), subsequent opts are ignored
+ if (curr_opt === '-' || curr_opt === '--') {
+ while (argv.length) {
+ cli.args.push(argv.shift());
+ }
+ return false;
+ }
+
+ //If the next element in argv isn't an opt, add it to the list of args
+ if (curr_opt[0] !== '-') {
+ cli.args.push(curr_opt);
+ return cli.next();
+ } else {
+ //Check if the opt is short/long
+ is_long = curr_opt[1] === '-';
+ curr_opt = curr_opt.substr(is_long ? 2 : 1);
+ }
+
+ //Accept grouped short opts, e.g. -abc => -a -b -c
+ if (!is_long && curr_opt.length > 1) {
+ short_tags = curr_opt.split('');
+ return cli.next();
+ }
+
+ var eq, len;
+
+ //Check if the long opt is in the form --option=VALUE
+ if (is_long && (eq = curr_opt.indexOf('=')) >= 0) {
+ curr_val = curr_opt.substr(eq + 1);
+ curr_opt = curr_opt.substr(0, eq);
+ len = curr_val.length;
+ //Allow values to be quoted
+ if ((curr_val[0] === '"' && curr_val[len - 1] === '"') ||
+ (curr_val[0] === "'" && curr_val[len - 1] === "'"))
+ {
+ curr_val = curr_val.substr(1, len-2);
+ }
+ if (curr_val.match(/^[0-9]+$/)) {
+ curr_val = parseInt(curr_val, 10);
+ }
+ }
+
+ //Save the opt representation for later
+ full_opt = (is_long ? '--' : '-') + curr_opt;
+
+ return curr_opt;
+};
+
+/**
+ * Parses command line opts.
+ *
+ * `opts` must be an object with opts defined like:
+ * long_tag: [short_tag, description, value_type, default_value];
+ *
+ * `commands` is an optional array or object for apps that are of the form
+ * my_app [OPTIONS] <command> [ARGS]
+ * The command list is output with usage information + there is bundled
+ * support for auto-completion, etc.
+ *
+ * See README.md for more information.
+ *
+ * @param {Object} opts
+ * @param {Object} commands (optional)
+ * @return {Object} opts (parsed)
+ * @api public
+ */
+cli.parse = function (opts, command_def) {
+ var default_val, i, parsed = cli.options, seen,
+ catch_all = !opts;
+ opt_list = opts || {};
+ commands = command_def;
+ command_list = commands || [];
+ if (commands && !Array.isArray(commands)) {
+ command_list = Object.keys(commands);
+ }
+ while (o = cli.next()) {
+ seen = false;
+ for (opt in opt_list) {
+ if (!(opt_list[opt] instanceof Array)) {
+ continue;
+ }
+ if (!opt_list[opt][0]) {
+ opt_list[opt][0] = opt;
+ }
+ if (o === opt || o === opt_list[opt][0]) {
+ seen = true;
+ if (opt_list[opt].length === 2) {
+ parsed[opt] = true;
+ break;
+ }
+ default_val = null;
+ if (opt_list[opt].length === 4) {
+ default_val = opt_list[opt][3];
+ }
+ if (opt_list[opt][2] instanceof Array) {
+ for (i = 0, l = opt_list[opt][2].length; i < l; i++) {
+ if (typeof opt_list[opt][2][i] === 'number') {
+ opt_list[opt][2][i] += '';
+ }
+ }
+ parsed[opt] = cli.getArrayValue(opt_list[opt][2], is_long ? null : default_val);
+ break;
+ }
+ if (opt_list[opt][2].toLowerCase) {
+ opt_list[opt][2] = opt_list[opt][2].toLowerCase();
+ }
+ switch (opt_list[opt][2]) {
+ case 'string': case 1: case true:
+ parsed[opt] = cli.getValue(default_val);
+ break;
+ case 'int': case 'number': case 'num':
+ case 'time': case 'seconds': case 'secs': case 'minutes': case 'mins':
+ case 'x': case 'n':
+ parsed[opt] = cli.getInt(default_val);
+ break;
+ case 'float': case 'decimal':
+ parsed[opt] = cli.getFloat(default_val);
+ break;
+ case 'path': case 'file': case 'directory': case 'dir':
+ parsed[opt] = cli.getPath(default_val, opt_list[opt][2]);
+ break;
+ case 'email':
+ parsed[opt] = cli.getEmail(default_val);
+ break;
+ case 'url': case 'uri': case 'domain': case 'host':
+ parsed[opt] = cli.getUrl(default_val, opt_list[opt][2]);
+ break;
+ case 'ip':
+ parsed[opt] = cli.getIp(default_val);
+ break;
+ case 'bool': case 'boolean': case 'on':
+ parsed[opt] = true;
+ break;
+ case 'false': case 'off': case false: case 0:
+ parsed[opt] = false;
+ break;
+ default:
+ cli.fatal('Unknown opt type "' + opt_list[opt][2] + '"');
+ }
+ break;
+ }
+ }
+ if (process.env.NODE_DISABLE_COLORS) {
+ no_color = true;
+ }
+ if (!seen) {
+ if (enable.help && (o === 'h' || o === 'help')) {
+ cli.getUsage();
+ process.exit();
+ } else if (enable.version && (o === 'v' || o === 'version')) {
+ if (cli.version == null) {
+ cli.parsePackageJson();
+ }
+ console.error(cli.app + ' v' + cli.version);
+ process.exit();
+ } else if (enable.daemon && (o === 'd' || o === 'daemon')) {
+ daemon_arg = cli.getArrayValue(['start','stop','restart','pid','log'], is_long ? null : 'start');
+ continue;
+ } else if (enable.catchall && (o === 'c' || o === 'catch')) {
+ continue;
+ } else if (enable.status && (o === 'k' || o === 'no-color' || o === 'debug')) {
+ no_color = (o === 'k' || o === 'no-color');
+ show_debug = o === 'debug';
+ continue;
+ } else if (enable.timeout && (o === 't' || o === 'timeout')) {
+ var secs = cli.getInt();
+ setTimeout(function () {
+ cli.fatal('Process timed out after ' + secs + 's');
+ }, secs * 1000);
+ continue;
+ } else if (catch_all) {
+ parsed[o] = curr_val || true;
+ continue;
+ }
+ cli.fatal('Unknown option ' + full_opt);
+ }
+ }
+ //Fill the remaining options with their default value or null
+ for (opt in opt_list) {
+ default_val = opt_list[opt].length === 4 ? opt_list[opt][3] : null;
+ if (!(opt_list[opt] instanceof Array)) {
+ parsed[opt] = opt_list[opt];
+ continue;
+ } else if (typeof parsed[opt] === 'undefined') {
+ parsed[opt] = default_val;
+ }
+ }
+ if (command_list.length) {
+ if (cli.args.length === 0) {
+ if (enable.help) {
+ cli.getUsage();
+ } else {
+ cli.fatal('A command is required (' + command_list.join(', ') + ').');
+ }
+ process.exit(1);
+ } else {
+ cli.command = cli.autocompleteCommand(cli.args.shift());
+ }
+ }
+ cli.argc = cli.args.length;
+ return parsed;
+};
+
+/**
+ * Helper method for matching a command from the command list.
+ *
+ * @param {String} command
+ * @return {String} full_command
+ * @api public
+ */
+cli.autocompleteCommand = function (command) {
+ var list;
+ if (!(command_list instanceof Array)) {
+ list = Object.keys(command_list);
+ } else {
+ list = command_list;
+ }
+ var i, j = 0, c = command.length, tmp_list;
+ if (list.length === 0 || list.indexOf(command) !== -1) {
+ return command;
+ }
+ for (i = 0; i < c; i++) {
+ tmp_list = [];
+ l = list.length;
+ if (l <= 1) break;
+ for (j = 0; j < l; j++)
+ if (list[j].length >= i && list[j][i] === command[i])
+ tmp_list.push(list[j]);
+ list = tmp_list;
+ }
+ l = list.length;
+ if (l === 1) {
+ return list[0];
+ } else if (l === 0) {
+ cli.fatal('Unknown command "' + command + '"' + (enable.help ? '. Please see --help for more information' : ''));
+ } else {
+ list.sort();
+ cli.fatal('The command "' + command + '" is ambiguous and could mean "' + list.join('", "') + '"');
+ }
+};
+
+/**
+ * Adds methods to output styled status messages to stderr.
+ *
+ * Added methods are cli.info(msg), cli.error(msg), cli.ok(msg), and
+ * cli.debug(msg).
+ *
+ * To control status messages, use the 'status' plugin
+ * 1) debug() messages are hidden by default. Display them with
+ * the --debug opt.
+ * 2) to hide all status messages, use the -s or --silent opt.
+ *
+ * @api private
+ */
+cli.status = function (msg, type) {
+ var pre;
+ switch (type) {
+ case 'info':
+ pre = no_color ? 'INFO:' : '\x1B[33mINFO\x1B[0m:';
+ break;
+ case 'debug':
+ pre = no_color ? 'DEBUG:' : '\x1B[36mDEBUG\x1B[0m:';
+ break;
+ case 'error':
+ case 'fatal':
+ pre = no_color ? 'ERROR:' : '\x1B[31mERROR\x1B[0m:';
+ break;
+ case 'ok':
+ pre = no_color ? 'OK:' : '\x1B[32mOK\x1B[0m:';
+ break;
+ }
+ msg = pre + ' ' + msg;
+ if (type === 'fatal') {
+ console.error(msg);
+ process.exit(1);
+ }
+ if (enable.status && !show_debug && type === 'debug') {
+ return;
+ }
+ console.error(msg);
+};
+['info','error','ok','debug','fatal'].forEach(function (type) {
+ cli[type] = function (msg) {
+ cli.status(msg, type);
+ };
+});
+
+/**
+ * Sets the app name and version.
+ *
+ * Usage:
+ * setApp('myapp', '0.1.0');
+ * setApp('./package.json'); //Pull name/version from package.json
+ *
+ * @param {String} name
+ * @return cli (for chaining)
+ * @api public
+ */
+cli.setApp = function (name, version) {
+ if (name.indexOf('package.json') !== -1) {
+ cli.parsePackageJson(name);
+ } else {
+ cli.app = name;
+ cli.version = version;
+ }
+ return cli;
+};
+
+/**
+ * Parses the version number from package.json. If no path is specified, cli
+ * will attempt to locate a package.json in ./, ../ or ../../
+ *
+ * @param {String} path (optional)
+ * @api public
+ */
+cli.parsePackageJson = function (path) {
+ var parse_packagejson = function (path) {
+ var packagejson = JSON.parse(cli.native.fs.readFileSync(path, 'utf8'));
+ cli.version = packagejson.version;
+ cli.app = packagejson.name;
+ };
+ var try_all = function (arr, func, err) {
+ for (var i = 0, l = arr.length; i < l; i++) {
+ try {
+ func(arr[i]);
+ return;
+ } catch (e) {
+ if (i === l-1) {
+ cli.fatal(err);
+ }
+ }
+ }
+ };
+ try {
+ if (path) {
+ return parse_packagejson(path);
+ }
+ try_all([
+ __dirname + '/package.json',
+ __dirname + '/../package.json',
+ __dirname + '/../../package.json'
+ ], parse_packagejson);
+ } catch (e) {
+ cli.fatal('Could not detect ' + cli.app + ' version');
+ }
+};
+
+/**
+ * Sets the usage string - default is `app [OPTIONS] [ARGS]`.
+ *
+ * @param {String} u
+ * @return cli (for chaining)
+ * @api public
+ */
+cli.setUsage = function (u) {
+ usage = u;
+ return cli;
+};
+
+var pad = function (str, len) {
+ if (typeof len === 'undefined') {
+ len = str;
+ str = '';
+ }
+ if (str.length < len) {
+ len -= str.length;
+ while (len--) str += ' ';
+ }
+ return str;
+};
+
+/**
+ * Automatically build usage information from the opts list. If the help
+ * plugin is enabled (default), this info is displayed with -h, --help.
+ *
+ * @api public
+ */
+cli.getUsage = function () {
+ var short, desc, optional, line, seen_opts = [],
+ switch_pad = cli.option_width;
+
+ var trunc_desc = function (pref, desc, len) {
+ var pref_len = pref.length,
+ desc_len = cli.width - pref_len,
+ truncated = '';
+ if (desc.length <= desc_len) {
+ return desc;
+ }
+ var desc_words = (desc+'').split(' '), chars = 0, word;
+ while (desc_words.length) {
+ truncated += (word = desc_words.shift()) + ' ';
+ chars += word.length;
+ if (desc_words.length && chars + desc_words[0].length > desc_len) {
+ truncated += '\n' + pad(pref_len);
+ chars = 0;
+ }
+ }
+ return truncated;
+ };
+
+ usage = usage || cli.app + ' [OPTIONS]' + (command_list.length ? ' <command>' : '') + ' [ARGS]';
+ if (no_color) {
+ console.error('Usage:\n ' + usage);
+ console.error('Options: ');
+ } else {
+ console.error('\x1b[1mUsage\x1b[0m:\n ' + usage);
+ console.error('\n\x1b[1mOptions\x1b[0m: ');
+ }
+ for (opt in opt_list) {
+
+ if (opt.length === 1) {
+ long = opt_list[opt][0];
+ short = opt;
+ } else {
+ long = opt;
+ short = opt_list[opt][0];
+ }
+
+ //Parse opt_list
+ desc = opt_list[opt][1].trim();
+ type = opt_list[opt].length >= 3 ? opt_list[opt][2] : null;
+ optional = opt_list[opt].length === 4 ? opt_list[opt][3] : null;
+
+ //Build usage line
+ if (short === long) {
+ if (short.length === 1) {
+ line = ' -' + short;
+ } else {
+ line = ' --' + long;
+ }
+ } else {
+ line = ' -' + short + ', --' + long;
+ }
+ line += ' ';
+
+ if (type) {
+ if (type instanceof Array) {
+ desc += '. VALUE must be either [' + type.join('|') + ']';
+ type = 'VALUE';
+ }
+ if (type === true || type === 1) {
+ type = long.toUpperCase();
+ }
+ type = type.toUpperCase();
+ if (type === 'FLOAT' || type === 'INT') {
+ type = 'NUMBER';
+ }
+ line += optional ? '[' + type + ']' : type;
+ }
+ line = pad(line, switch_pad);
+ line += trunc_desc(line, desc);
+ line += optional ? ' (Default is ' + optional + ')' : '';
+ console.error(line.replace('%s', '%\0s'));
+
+ seen_opts.push(short);
+ seen_opts.push(long);
+ }
+ if (enable.timeout && seen_opts.indexOf('t') === -1 && seen_opts.indexOf('timeout') === -1) {
+ console.error(pad(' -t, --timeout N', switch_pad) + 'Exit if the process takes longer than N seconds');
+ }
+ if (enable.status) {
+ if (seen_opts.indexOf('k') === -1 && seen_opts.indexOf('no-color') === -1) {
+ console.error(pad(' -k, --no-color', switch_pad) + 'Omit color from output');
+ }
+ if (seen_opts.indexOf('debug') === -1) {
+ console.error(pad(' --debug', switch_pad) + 'Show debug information');
+ }
+ }
+ if (enable.catchall && seen_opts.indexOf('c') === -1 && seen_opts.indexOf('catch') === -1) {
+ console.error(pad(' -c, --catch', switch_pad) + 'Catch unanticipated errors');
+ }
+ if (enable.daemon && seen_opts.indexOf('d') === -1 && seen_opts.indexOf('daemon') === -1) {
+ console.error(pad(' -d, --daemon [ARG]', switch_pad) + 'Daemonize the process. Control the daemon using [start, stop, restart, log, pid]');
+ }
+ if (enable.version && seen_opts.indexOf('v') === -1 && seen_opts.indexOf('version') === -1) {
+ console.error(pad(' -v, --version', switch_pad) + 'Display the current version');
+ }
+ if (enable.help && seen_opts.indexOf('h') === -1 && seen_opts.indexOf('help') === -1) {
+ console.error(pad(' -h, --help', switch_pad) + 'Display help and usage details');
+ }
+ if (command_list.length) {
+ console.error('\n\x1b[1mCommands\x1b[0m: ');
+ if (!Array.isArray(commands)) {
+ for (var c in commands) {
+ line = ' ' + pad(c, switch_pad - 2);
+ line += trunc_desc(line, commands[c]);
+ console.error(line);
+ }
+ } else {
+ command_list.sort();
+ console.error(' ' + trunc_desc(' ', command_list.join(', ')));
+ }
+ }
+ process.exit();
+};
+
+/**
+ * Generates an error message when an opt is incorrectly used.
+ *
+ * @param {String} expects (e.g. 'a value')
+ * @param {String} type (e.g. 'VALUE')
+ * @api public
+ */
+cli.getOptError = function (expects, type) {
+ var err = full_opt + ' expects ' + expects
+ + '. Use `' + cli.app + ' ' + full_opt + (is_long ? '=' : ' ') + type + '`';
+ return err;
+};
+
+/**
+ * Gets the next opt value and validates it with an optional validation
+ * function. If validation fails or no value can be obtained, this method
+ * will return the default value (if specified) or exit with err_msg.
+ *
+ * @param {String} default_val
+ * @param {Function} validate_func
+ * @param {String} err_msg
+ * @api public
+ */
+cli.getValue = function (default_val, validate_func, err_msg) {
+ err_msg = err_msg || cli.getOptError('a value', 'VALUE');
+
+ var value;
+
+ try {
+ if (curr_val) {
+ if (validate_func) {
+ curr_val = validate_func(curr_val);
+ }
+ return curr_val;
+ }
+
+ //Grouped short opts aren't allowed to have values
+ if (short_tags.length) {
+ throw 'Short tags';
+ }
+
+ //If there's no args left or the next arg is an opt, return the
+ //default value (if specified) - otherwise fail
+ if (!argv.length || (argv[0].length === 1 && argv[0][0] === '-')) {
+ throw 'No value';
+ }
+
+ value = argv.shift();
+
+ if (value.match(/^[0-9]+$/)) {
+ value = parseInt(value, 10);
+ }
+
+ //Run the value through a validation/transformation function if specified
+ if (validate_func) {
+ value = validate_func(value);
+ }
+ } catch (e) {
+
+ //The value didn't pass the validation/transformation. Unshift the value and
+ //return the default value (if specified)
+ if (value) {
+ argv.unshift(value);
+ }
+ return default_val != null ? default_val : cli.fatal(err_msg);
+ }
+ return value;
+};
+
+cli.getInt = function (default_val) {
+ return cli.getValue(default_val, function (value) {
+ if (typeof value === 'number') return value;
+ if (!value.match(/^(?:-?(?:0|[1-9][0-9]*))$/)) {
+ throw 'Invalid int';
+ }
+ return parseInt(value);
+ }, cli.getOptError('a number', 'NUMBER'));
+}
+
+cli.getFloat = function (default_val) {
+ return cli.getValue(default_val, function (value) {
+ if (!value.match(/^(?:-?(?:0|[1-9][0-9]*))?(?:\.[0-9]*)?$/)) {
+ throw 'Invalid float';
+ }
+ return parseFloat(value, 10);
+ }, cli.getOptError('a number', 'NUMBER'));
+}
+
+cli.getUrl = function (default_val, identifier) {
+ identifier = identifier || 'url';
+ return cli.getValue(default_val, function (value) {
+ if (!value.match(/^(?:(?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?:\w+:\w+@)?((?:(?:[-\w\d{1-3}]+\.)+(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|edu|co\.uk|ac\.uk|it|fr|tv|museum|asia|local|travel|[a-z]{2})?)|((\b25[0-5]\b|\b[2][0-4][0-9]\b|\b[0-1]?[0-9]?[0-9]\b)(\.(\b25[0-5]\b|\b[2][0-4][0-9]\b|\b[0-1]?[0-9]?[0-9]\b)){3}))(?::[\d]{1,5})?(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?:#(?:[-\w~!$ |\/.,*:;=]|%[a-f\d]{2})*)?$/i)) {
+ throw 'Invalid URL';
+ }
+ return value;
+ }, cli.getOptError('a ' + identifier, identifier.toUpperCase()));
+}
+
+cli.getEmail = function (default_val) {
+ return cli.getValue(default_val, function (value) {
+ if (!value.match(/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/)) {
+ throw 'Invalid email';
+ }
+ return value;
+ }, cli.getOptError('an email', 'EMAIL'));
+}
+
+cli.getIp = function (default_val) {
+ return cli.getValue(default_val, function (value) {
+ if (!value.match(/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/)) {
+ throw 'Invalid IP';
+ }
+ return value;
+ }, cli.getOptError('an IP', 'IP'));
+}
+
+cli.getPath = function (default_val, identifier) {
+ identifier = identifier || 'path';
+ return cli.getValue(default_val, function (value) {
+ if (value.match(/[?*:;{}]/)) {
+ throw 'Invalid path';
+ }
+ return value;
+ }, cli.getOptError('a ' + identifier, identifier.toUpperCase()));
+}
+
+cli.getArrayValue = function (arr, default_val) {
+ return cli.getValue(default_val, function (value) {
+ if (arr.indexOf(value) === -1) {
+ throw 'Unexpected value';
+ }
+ return value;
+ }, cli.getOptError('either [' + arr.join('|') + ']', 'VALUE'));
+}
+
+/**
+ * Gets all data from STDIN (with optional encoding) and sends it to callback.
+ *
+ * @param {String} encoding (optional - default is 'utf8')
+ * @param {Function} callback
+ * @api public
+ */
+cli.withStdin = function (encoding, callback) {
+ if (typeof encoding === 'function') {
+ callback = encoding;
+ encoding = 'utf8';
+ }
+ var stream = process.openStdin(), data = '';
+ stream.setEncoding(encoding);
+ stream.on('data', function (chunk) {
+ data += chunk;
+ });
+ stream.on('end', function () {
+ callback.apply(cli, [data]);
+ });
+};
+
+/**
+ * Gets all data from STDIN, splits the data into lines and sends it
+ * to callback (callback isn't called until all of STDIN is read. To
+ * process each line as it's received, see the method below
+ *
+ * @param {Function} callback
+ * @api public
+ */
+cli.withStdinLines = function (callback) {
+ cli.withStdin(function (data) {
+ var sep = data.indexOf('\r\n') !== -1 ? '\r\n' : '\n';
+ callback.apply(cli, [data.split(sep), sep]);
+ });
+};
+
+/**
+ * Asynchronously reads a file line by line. When a line is received,
+ * callback is called with (line, sep) - when EOF is reached, callback
+ * receives (null, null, true)
+ *
+ * @param {String} file (optional - default is 'stdin')
+ * @param {String} encoding (optional - default is 'utf8')
+ * @param {Function} callback (line, sep, eof)
+ * @api public
+ */
+cli.withInput = function (file, encoding, callback) {
+ if (typeof encoding === 'function') {
+ callback = encoding;
+ encoding = 'utf8';
+ } else if (typeof file === 'function') {
+ callback = file;
+ encoding = 'utf8';
+ file = 'stdin';
+ }
+ if (file === 'stdin') {
+ file = process.openStdin();
+ } else {
+ try {
+ file = cli.native.fs.createReadStream(file);
+ file.on('error', cli.fatal);
+ } catch (e) {
+ return cli.fatal(e);
+ }
+ }
+ file.setEncoding(encoding);
+ var lines = [], data = '', eof, sep;
+ file.on('data', function (chunk) {
+ if (eof) return;
+ data += chunk;
+ if (!sep) {
+ if (data.indexOf('\r\n') !== -1) {
+ sep = '\r\n';
+ } else if (data.indexOf('\n') !== -1) {
+ sep = '\n';
+ } else {
+ last_line = data;
+ return;
+ }
+ }
+ lines = data.split(sep);
+ data = eof ? null : lines.pop();
+ while (lines.length) {
+ callback.apply(cli, [lines.shift(), sep, false]);
+ }
+ });
+ file.on('end', function () {
+ eof = true;
+ if (data.length) {
+ callback.apply(cli, [data, sep || '', false]);
+ }
+ callback.apply(cli, [null, null, true]);
+ });
+};
+
+/**
+ * A method for creating and controlling a daemon.
+ *
+ * `arg` can be:
+ * start = daemonizes the process
+ * stop = stops the daemon if it is running
+ * restart = alias for stop -> start
+ * pid = outputs the daemon's PID if it is running
+ * log = outputs the daemon's log file (stdout + stderr)
+ *
+ * @param {String} arg (Optional - default is 'start')
+ * @param {Function} callback
+ * @api public
+ */
+cli.daemon = function (arg, callback) {
+ if (typeof daemon === 'undefined') {
+ cli.fatal('Daemon is not initialized');
+ }
+
+ if (typeof arg === 'function') {
+ callback = arg;
+ arg = 'start';
+ }
+
+ var lock_file = '/tmp/' + cli.app + '.pid',
+ log_file = '/tmp/' + cli.app + '.log';
+
+ var start = function () {
+ daemon.daemonize(log_file, lock_file, function (err) {
+ if (err) return cli.error('Error starting daemon: ' + err);
+ callback();
+ });
+ };
+
+ var stop = function () {
+ try {
+ cli.native.fs.readFileSync(lock_file);
+ } catch (e) {
+ return cli.error('Daemon is not running');
+ };
+ daemon.kill(lock_file, function (err, pid) {
+ if (err && err.errno === 3) {
+ return cli.error('Daemon is not running');
+ } else if (err) {
+ return cli.error('Error stopping daemon: ' + err.errno);
+ }
+ cli.ok('Successfully stopped daemon with pid: ' + pid);
+ });
+ };
+
+ switch(arg) {
+ case 'stop':
+ stop();
+ break;
+ case 'restart':
+ daemon.stop(lock_file, function () {
+ start();
+ });
+ break;
+ case 'log':
+ try {
+ cli.native.fs.createReadStream(log_file, {encoding: 'utf8'}).pipe(process.stdout);
+ } catch (e) {
+ return cli.error('No daemon log file');
+ };
+ break;
+ case 'pid':
+ try {
+ var pid = cli.native.fs.readFileSync(lock_file, 'utf8');
+ cli.native.fs.statSync('/proc/' + pid);
+ cli.info(pid);
+ } catch (e) {
+ return cli.error('Daemon is not running');
+ };
+ break;
+ default:
+ start();
+ break;
+ }
+}
+
+/**
+ * The main entry method. Calling cli.main() is only necessary in
+ * scripts that have daemon support enabled. `callback` receives (args, options)
+ *
+ * @param {Function} callback
+ * @api public
+ */
+cli.main = function (callback) {
+ var after = function () {
+ callback.apply(cli, [cli.args, cli.options]);
+ };
+ if (enable.daemon && daemon_arg) {
+ cli.daemon(daemon_arg, after);
+ } else {
+ after();
+ }
+}
+
+/**
+ * Bind creationix's stack (https://github.com/creationix/stack).
+ *
+ * Create a simple middleware stack by calling:
+ *
+ * cli.createServer(middleware).listen(port);
+ *
+ * @return {Server} server
+ * @api public
+ */
+cli.createServer = function(/*layers*/) {
+ var defaultStackErrorHandler = function (req, res, err) {
+ if (err) {
+ console.error(err.stack);
+ res.writeHead(500, {"Content-Type": "text/plain"});
+ return res.end(err.stack + "\n");
+ }
+ res.writeHead(404, {"Content-Type": "text/plain"});
+ res.end("Not Found\n");
+ };
+ var handle = error = defaultStackErrorHandler,
+ layers = Array.prototype.slice.call(arguments);
+
+ //Allow createServer(a,b,c) and createServer([a,b,c])
+ if (layers.length && layers[0] instanceof Array) {
+ layers = layers[0];
+ }
+ layers.reverse().forEach(function (layer) {
+ var child = handle;
+ handle = function (req, res) {
+ try {
+ layer(req, res, function (err) {
+ if (err) return error(req, res, err);
+ child(req, res);
+ });
+ } catch (err) {
+ error(req, res, err);
+ }
+ };
+ });
+ return cli.native.http.createServer(handle);
+};
+
+/**
+ * A wrapper for child_process.exec().
+ *
+ * If the child_process exits successfully, `callback` receives an array of
+ * stdout lines. The current process exits if the child process has an error
+ * and `errback` isn't defined.
+ *
+ * @param {String} cmd
+ * @param {Function} callback (optional)
+ * @param {Function} errback (optional)
+ * @api public
+ */
+cli.exec = function (cmd, callback, errback) {
+ cli.native.child_process.exec(cmd, function (err, stdout, stderr) {
+ err = err || stderr;
+ if (err) {
+ if (errback) {
+ return errback(err, stdout);
+ }
+ return cli.fatal('exec() failed\n' + err);
+ }
+ if (callback) {
+ callback(stdout.split('\n'));
+ }
+ });
+};
+
+/**
+ * Helper method for outputting a progress bar to the console.
+ *
+ * @param {Number} progress (0 <= progress <= 1)
+ * @api public
+ */
+var last_progress_call, progress_len = 74;
+cli.progress = function (progress, decimals) {
+ if (progress < 0 || progress > 1 || isNaN(progress)) return;
+ if (!decimals) decimals = 0;
+ var now = (new Date()).getTime();
+ if (last_progress_call && (now - last_progress_call) < 100 && progress !== 1) {
+ return; //Throttle progress calls
+ }
+ last_progress_call = now;
+
+
+ var barLength = Math.floor(progress_len * progress),
+ str = '';
+ if (barLength == 0 && progress > 0) {
+ barLength = 1;
+ }
+ for (var i = 1; i <= progress_len; i++) {
+ str += i <= barLength ? '#' : ' ';
+ }
+ var pwr = Math.pow(10, decimals);
+ var percentage = Math.floor(progress * 100 * pwr) / pwr + '%';
+ for (i = 0; i < decimals; i++) {
+ percentage += ' ';
+ }
+ cli.native.util.print('[' + str + '] ' + percentage + (progress === 1 ? '\n' : '\u000D'));
+};
+
+/**
+ * Helper method for outputting a spinner to the console.
+ *
+ * @param {String|Boolean} prefix (optional)
+ * @api public
+ */
+var spinnerInterval;
+cli.spinner = function (prefix, end) {
+ if (end) {
+ cli.native.util.print('\u000D' + prefix);
+ return clearInterval(spinnerInterval);
+ }
+ prefix = prefix + ' ' || '';
+ var spinner = ['-','\\','|','/'], i = 0, l = spinner.length;
+ spinnerInterval = setInterval(function () {
+ cli.native.util.print('\u000D' + prefix + spinner[i++]);
+ if (i == l) i = 0;
+ }, 200);
+};
View
17 Support/node_modules/cli/examples/cat.js
@@ -0,0 +1,17 @@
+#!/usr/bin/env node
+
+var cli = require('cli');
+
+var output_file = function (file) {
+ cli.withInput(file, function (line, sep, eof) {
+ if (!eof) {
+ cli.output(line + sep);
+ } else if (cli.args.length) {
+ output_file(cli.args.shift());
+ }
+ });
+};
+
+if (cli.args.length) {
+ output_file(cli.args.shift());
+}
View
16 Support/node_modules/cli/examples/command.js
@@ -0,0 +1,16 @@
+#!/usr/bin/env node
+
+var cli = require('cli');
+
+//The second (optional) argument of cli.parse() is a command list
+//Type `./command.js --help` for usage info
+
+//cli enables auto-completion of commands (similiar to npm), e.g. all of
+//the following are equivalent and result in "Command is: install":
+// $ ./command.js install
+// $ ./command.js inst
+// $ ./command.js i
+
+cli.parse(null, ['install', 'test', 'edit', 'remove', 'uninstall', 'ls']);
+
+console.log('Command is: ' + cli.command);
View
54 Support/node_modules/cli/examples/echo.js
@@ -0,0 +1,54 @@
+#!/usr/bin/env node
+
+/* All of the following commands are equivalent and write `foo\tbar foo` to out.txt
+ $ ./echo.js -n -e --output=out.txt "foo\tbar" "foo"
+ $ ./echo.js --newline --escape --output "out.txt" "foo\tbar" "foo"
+ $ ./echo.js -ne --output=out.txt "foo\tbar" "foo"
+ $ ./echo.js -en --output="out.txt" "foo\tbar" "foo"
+*/
+
+var cli = require('cli');
+
+cli.parse({
+ newline: ['n', 'Do not output the trailing newline'],
+ escape: ['e', 'Enable interpretation of backslash escapes'],
+ separator: ['s', 'Separate arguments using this value', 'string', ' '],
+ output: [false, 'Write to FILE rather than the console', 'file']
+});
+
+cli.main(function (args, options) {
+ var output = '', i, j, l, output_stream;
+
+ if (this.argc) {
+ if (options.escape) {
+ var replace = {'\\n':'\n','\\r':'\r','\\t':'\t','\\e':'\e','\\v':'\v','\\f':'\f','\\c':'\c','\\b':'\b','\\a':'\a','\\\\':'\\'};
+ var escape = function (str) {
+ string += '';
+ for (j in replace) {
+ string = string.replace(i, replace[i]);
+ }
+ return string;
+ }
+ for (i = 0, l = this.argc; i < l; i++) {
+ args[i] = escape(args[i]);
+ }
+ options.separator = escape(options.separator);
+ }
+ output += args.join(options.separator);
+ }
+
+ if (!options.newline) {
+ output += '\n';
+ }
+
+ try {
+ if (options.output) {
+ output_stream = this.native.fs.createWriteStream(options.output)
+ } else {
+ output_stream = process.stdout;
+ }
+ output_stream.write(output);
+ } catch (e) {
+ this.fatal('Could not write to output stream');
+ }
+});
View
6 Support/node_modules/cli/examples/glob.js
@@ -0,0 +1,6 @@
+#!/usr/bin/env node
+
+var cli = require('cli').enable('glob');
+
+//Running `./glob.js *.js` will output a list of .js files in this directory
+console.log(cli.args);
View
20 Support/node_modules/cli/examples/long_desc.js
@@ -0,0 +1,20 @@
+#!/usr/bin/env node
+
+var cli = require('../');
+
+//You can (optionally) boost the width of output with:
+//cli.width = 120;
+
+//You can also adjust the width of the options/command definitions
+//cli.option_width = 25;
+
+var long_desc = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s '
+ + 'standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make'
+ + ' a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, '
+ + 'remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing '
+ + 'Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions'
+ + ' of Lorem Ipsum.';
+
+cli.parse({
+ foo: ['f', long_desc]
+});
View
11 Support/node_modules/cli/examples/progress.js
@@ -0,0 +1,11 @@
+#!/usr/bin/env node
+
+var cli = require('cli');
+
+var i = 0, interval = setInterval(function () {
+ cli.progress(++i / 100);
+ if (i === 100) {
+ clearInterval(interval);
+ cli.ok('Finished!');
+ }
+}, 50);
View
18 Support/node_modules/cli/examples/sort.js
@@ -0,0 +1,18 @@
+#!/usr/bin/env node
+
+var cli = require('cli');
+
+var options = cli.parse({
+ numeric: ['n', 'Compare using a numeric sort'],
+ reverse: ['r', 'Reverse the results']
+});
+
+cli.withStdinLines(function (lines, newline) {
+ lines.sort(!options.numeric ? null : function (a, b) {
+ return parseInt(a) > parseInt(b);
+ });
+ if (options.reverse) {
+ lines.reverse();
+ }
+ this.output(lines.join(newline));
+});
View
9 Support/node_modules/cli/examples/spinner.js
@@ -0,0 +1,9 @@
+#!/usr/bin/env node
+
+var cli = require('cli');
+
+cli.spinner('Working..');
+
+setTimeout(function () {
+ cli.spinner('Working.. done!', true); //End the spinner
+}, 3000);
View
27 Support/node_modules/cli/examples/static.coffee
@@ -0,0 +1,27 @@
+#!/usr/bin/env coffee
+
+cli = require 'cli'
+
+cli.enable('daemon','status')
+ .setUsage('static.coffee [OPTIONS]')
+
+cli.parse {
+ log: ['l', 'Enable logging']
+ port: ['p', 'Listen on this port', 'number', 8080]
+ serve: [false, 'Serve static files from PATH', 'path', './public']
+}
+
+middleware = []
+
+cli.main (args, options) ->
+
+ if options.log
+ @debug 'Enabling logging'
+ middleware.push require('creationix/log')()
+
+ @debug 'Serving files from ' + options.serve
+ middleware.push require('creationix/static')('/', options.serve, 'index.html')
+
+ server = @createServer(middleware).listen options.port
+
+ @ok 'Listening on port ' + options.port
View
25 Support/node_modules/cli/examples/static.js
@@ -0,0 +1,25 @@
+#!/usr/bin/env node
+
+var cli = require('cli').enable('status', 'daemon');
+
+cli.parse({
+ log: ['l', 'Enable logging'],
+ port: ['p', 'Listen on this port', 'number', 8080],
+ serve: [false, 'Serve static files from PATH', 'path', './public']
+});
+
+cli.main(function (args, options) {
+ var server, middleware = [];
+
+ if (options.log) {
+ this.debug('Enabling logging');
+ middleware.push(require('creationix/log')());
+ }
+
+ this.debug('Serving files from ' + options.serve);
+ middleware.push(require('creationix/static')('/', options.serve, 'index.html'));
+
+ server = this.createServer(middleware).listen(options.port);
+
+ this.ok('Listening on port ' + options.port);
+});
View
1  Support/node_modules/cli/index.js
@@ -0,0 +1 @@
+module.exports = require('./cli');
View
2  Support/node_modules/cli/node_modules/glob/.npmignore
@@ -0,0 +1,2 @@
+.*.swp
+test/a/
View
3  Support/node_modules/cli/node_modules/glob/.travis.yml
@@ -0,0 +1,3 @@
+language: node_js
+node_js:
+ - 0.8
View
27 Support/node_modules/cli/node_modules/glob/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) Isaac Z. Schlueter ("Author")
+All rights reserved.
+
+The BSD License
+
+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 THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR 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.
View
250 Support/node_modules/cli/node_modules/glob/README.md
@@ -0,0 +1,250 @@
+# Glob
+
+Match files using the patterns the shell uses, like stars and stuff.
+
+This is a glob implementation in JavaScript. It uses the `minimatch`
+library to do its matching.
+
+## Attention: node-glob users!
+
+The API has changed dramatically between 2.x and 3.x. This library is
+now 100% JavaScript, and the integer flags have been replaced with an
+options object.
+
+Also, there's an event emitter class, proper tests, and all the other
+things you've come to expect from node modules.
+
+And best of all, no compilation!
+
+## Usage
+
+```javascript
+var glob = require("glob")
+
+// options is optional
+glob("**/*.js", options, function (er, files) {
+ // files is an array of filenames.
+ // If the `nonull` option is set, and nothing
+ // was found, then files is ["**/*.js"]
+ // er is an error object or null.
+})
+```
+
+## Features
+
+Please see the [minimatch
+documentation](https://github.com/isaacs/minimatch) for more details.
+
+Supports these glob features:
+
+* Brace Expansion
+* Extended glob matching
+* "Globstar" `**` matching
+
+See:
+
+* `man sh`
+* `man bash`
+* `man 3 fnmatch`
+* `man 5 gitignore`
+* [minimatch documentation](https://github.com/isaacs/minimatch)
+
+## glob(pattern, [options], cb)
+
+* `pattern` {String} Pattern to be matched
+* `options` {Object}
+* `cb` {Function}
+ * `err` {Error | null}
+ * `matches` {Array<String>} filenames found matching the pattern
+
+Perform an asynchronous glob search.
+
+## glob.sync(pattern, [options])
+
+* `pattern` {String} Pattern to be matched
+* `options` {Object}
+* return: {Array<String>} filenames found matching the pattern
+
+Perform a synchronous glob search.
+
+## Class: glob.Glob
+
+Create a Glob object by instanting the `glob.Glob` class.
+
+```javascript
+var Glob = require("glob").Glob
+var mg = new Glob(pattern, options, cb)
+```
+
+It's an EventEmitter, and starts walking the filesystem to find matches
+immediately.
+
+### new glob.Glob(pattern, [options], [cb])
+
+* `pattern` {String} pattern to search for
+* `options` {Object}
+* `cb` {Function} Called when an error occurs, or matches are found
+ * `err` {Error | null}
+ * `matches` {Array<String>} filenames found matching the pattern
+
+Note that if the `sync` flag is set in the options, then matches will
+be immediately available on the `g.found` member.
+
+### Properties
+
+* `minimatch` The minimatch object that the glob uses.
+* `options` The options object passed in.
+* `error` The error encountered. When an error is encountered, the
+ glob object is in an undefined state, and should be discarded.
+* `aborted` Boolean which is set to true when calling `abort()`. There
+ is no way at this time to continue a glob search after aborting, but
+ you can re-use the statCache to avoid having to duplicate syscalls.
+* `statCache` Collection of all the stat results the glob search
+ performed.
+* `cache` Convenience object. Each field has the following possible
+ values:
+ * `false` - Path does not exist
+ * `true` - Path exists
+ * `1` - Path exists, and is not a directory
+ * `2` - Path exists, and is a directory
+ * `[file, entries, ...]` - Path exists, is a directory, and the
+ array value is the results of `fs.readdir`
+
+### Events
+
+* `end` When the matching is finished, this is emitted with all the
+ matches found. If the `nonull` option is set, and no match was found,
+ then the `matches` list contains the original pattern. The matches
+ are sorted, unless the `nosort` flag is set.
+* `match` Every time a match is found, this is emitted with the matched.
+* `error` Emitted when an unexpected error is encountered, or whenever
+ any fs error occurs if `options.strict` is set.
+* `abort` When `abort()` is called, this event is raised.
+
+### Methods
+
+* `abort` Stop the search.
+
+### Options
+
+All the options that can be passed to Minimatch can also be passed to
+Glob to change pattern matching behavior. Also, some have been added,
+or have glob-specific ramifications.
+
+All options are false by default, unless otherwise noted.
+
+All options are added to the glob object, as well.
+
+* `cwd` The current working directory in which to search. Defaults
+ to `process.cwd()`.
+* `root` The place where patterns starting with `/` will be mounted
+ onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix
+ systems, and `C:\` or some such on Windows.)
+* `dot` Include `.dot` files in normal matches and `globstar` matches.
+ Note that an explicit dot in a portion of the pattern will always
+ match dot files.
+* `nomount` By default, a pattern starting with a forward-slash will be
+ "mounted" onto the root setting, so that a valid filesystem path is
+ returned. Set this flag to disable that behavior.
+* `mark` Add a `/` character to directory matches. Note that this
+ requires additional stat calls.
+* `nosort` Don't sort the results.
+* `stat` Set to true to stat *all* results. This reduces performance
+ somewhat, and is completely unnecessary, unless `readdir` is presumed
+ to be an untrustworthy indicator of file existence. It will cause
+ ELOOP to be triggered one level sooner in the case of cyclical
+ symbolic links.
+* `silent` When an unusual error is encountered
+ when attempting to read a directory, a warning will be printed to
+ stderr. Set the `silent` option to true to suppress these warnings.
+* `strict` When an unusual error is encountered
+ when attempting to read a directory, the process will just continue on
+ in search of other matches. Set the `strict` option to raise an error
+ in these cases.
+* `cache` See `cache` property above. Pass in a previously generated
+ cache object to save some fs calls.
+* `statCache` A cache of results of filesystem information, to prevent
+ unnecessary stat calls. While it should not normally be necessary to
+ set this, you may pass the statCache from one glob() call to the
+ options object of another, if you know that the filesystem will not
+ change between calls. (See "Race Conditions" below.)
+* `sync` Perform a synchronous glob search.
+* `nounique` In some cases, brace-expanded patterns can result in the
+ same file showing up multiple times in the result set. By default,
+ this implementation prevents duplicates in the result set.
+ Set this flag to disable that behavior.
+* `nonull` Set to never return an empty set, instead returning a set
+ containing the pattern itself. This is the default in glob(3).
+* `nocase` Perform a case-insensitive match. Note that case-insensitive
+ filesystems will sometimes result in glob returning results that are
+ case-insensitively matched anyway, since readdir and stat will not
+ raise an error.
+* `debug` Set to enable debug logging in minimatch and glob.
+* `globDebug` Set to enable debug logging in glob, but not minimatch.
+
+## Comparisons to other fnmatch/glob implementations
+
+While strict compliance with the existing standards is a worthwhile
+goal, some discrepancies exist between node-glob and other
+implementations, and are intentional.
+
+If the pattern starts with a `!` character, then it is negated. Set the
+`nonegate` flag to suppress this behavior, and treat leading `!`
+characters normally. This is perhaps relevant if you wish to start the
+pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
+characters at the start of a pattern will negate the pattern multiple
+times.
+
+If a pattern starts with `#`, then it is treated as a comment, and
+will not match anything. Use `\#` to match a literal `#` at the
+start of a line, or set the `nocomment` flag to suppress this behavior.
+
+The double-star character `**` is supported by default, unless the
+`noglobstar` flag is set. This is supported in the manner of bsdglob
+and bash 4.1, where `**` only has special significance if it is the only
+thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
+`a/**b` will not.
+
+If an escaped pattern has no matches, and the `nonull` flag is set,
+then glob returns the pattern as-provided, rather than
+interpreting the character escapes. For example,
+`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
+`"*a?"`. This is akin to setting the `nullglob` option in bash, except
+that it does not resolve escaped pattern characters.
+
+If brace expansion is not disabled, then it is performed before any
+other interpretation of the glob pattern. Thus, a pattern like
+`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
+**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
+checked for validity. Since those two are valid, matching proceeds.
+
+## Windows
+
+**Please only use forward-slashes in glob expressions.**
+
+Though windows uses either `/` or `\` as its path separator, only `/`
+characters are used by this glob implementation. You must use
+forward-slashes **only** in glob expressions. Back-slashes will always
+be interpreted as escape characters, not path separators.
+
+Results from absolute patterns such as `/foo/*` are mounted onto the
+root setting using `path.join`. On windows, this will by default result
+in `/foo/*` matching `C:\foo\bar.txt`.
+
+## Race Conditions
+
+Glob searching, by its very nature, is susceptible to race conditions,
+since it relies on directory walking and such.
+
+As a result, it is possible that a file that exists when glob looks for
+it may have been deleted or modified by the time it returns the result.
+
+As part of its internal implementation, this program caches all stat
+and readdir calls that it makes, in order to cut down on system
+overhead. However, this also makes it even more susceptible to races,
+especially if the cache or statCache objects are reused between glob
+calls.
+
+Users are thus advised not to use a glob result as a guarantee of
+filesystem state in the face of rapid changes. For the vast majority
+of operations, this is never a problem.
View
9 Support/node_modules/cli/node_modules/glob/examples/g.js
@@ -0,0 +1,9 @@
+var Glob = require("../").Glob
+
+var pattern = "test/a/**/[cg]/../[cg]"
+console.log(pattern)
+
+var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) {
+ console.log("matches", matches)
+})
+console.log("after")
View
9 Support/node_modules/cli/node_modules/glob/examples/usr-local.js
@@ -0,0 +1,9 @@
+var Glob = require("../").Glob
+
+var pattern = "{./*/*,/*,/usr/local/*}"
+console.log(pattern)
+
+var mg = new Glob(pattern, {mark: true}, function (er, matches) {
+ console.log("matches", matches)
+})
+console.log("after")
View
675 Support/node_modules/cli/node_modules/glob/glob.js
@@ -0,0 +1,675 @@
+// Approach:
+//
+// 1. Get the minimatch set
+// 2. For each pattern in the set, PROCESS(pattern)
+// 3. Store matches per-set, then uniq them
+//
+// PROCESS(pattern)
+// Get the first [n] items from pattern that are all strings
+// Join these together. This is PREFIX.
+// If there is no more remaining, then stat(PREFIX) and
+// add to matches if it succeeds. END.
+// readdir(PREFIX) as ENTRIES
+// If fails, END
+// If pattern[n] is GLOBSTAR
+// // handle the case where the globstar match is empty
+// // by pruning it out, and testing the resulting pattern
+// PROCESS(pattern[0..n] + pattern[n+1 .. $])
+// // handle other cases.
+// for ENTRY in ENTRIES (not dotfiles)
+// // attach globstar + tail onto the entry
+// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $])
+//
+// else // not globstar
+// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
+// Test ENTRY against pattern[n]
+// If fails, continue
+// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
+//
+// Caveat:
+// Cache all stats and readdirs results to minimize syscall. Since all
+// we ever care about is existence and directory-ness, we can just keep
+// `true` for files, and [children,...] for directories, or `false` for
+// things that don't exist.
+
+
+
+module.exports = glob
+
+var fs = require("fs")
+, minimatch = require("minimatch")
+, Minimatch = minimatch.Minimatch
+, inherits = require("inherits")
+, EE = require("events").EventEmitter
+, path = require("path")
+, isDir = {}
+, assert = require("assert").ok
+
+function glob (pattern, options, cb) {
+ if (typeof options === "function") cb = options, options = {}
+ if (!options) options = {}
+
+ if (typeof options === "number") {
+ deprecated()
+ return
+ }
+
+ var g = new Glob(pattern, options, cb)
+ return g.sync ? g.found : g
+}
+
+glob.fnmatch = deprecated
+
+function deprecated () {
+ throw new Error("glob's interface has changed. Please see the docs.")
+}
+
+glob.sync = globSync
+function globSync (pattern, options) {
+ if (typeof options === "number") {
+ deprecated()
+ return
+ }
+
+ options = options || {}
+ options.sync = true
+ return glob(pattern, options)
+}
+
+
+glob.Glob = Glob
+inherits(Glob, EE)
+function Glob (pattern, options, cb) {
+ if (!(this instanceof Glob)) {
+ return new Glob(pattern, options, cb)
+ }
+
+ if (typeof cb === "function") {
+ this.on("error", cb)
+ this.on("end", function (matches) {
+ cb(null, matches)
+ })
+ }
+
+ options = options || {}
+
+ this.EOF = {}
+ this._emitQueue = []
+
+ this.maxDepth = options.maxDepth || 1000
+ this.maxLength = options.maxLength || Infinity
+ this.cache = options.cache || {}
+ this.statCache = options.statCache || {}
+
+ this.changedCwd = false
+ var cwd = process.cwd()
+ if (!options.hasOwnProperty("cwd")) this.cwd = cwd
+ else {
+ this.cwd = options.cwd
+ this.changedCwd = path.resolve(options.cwd) !== cwd
+ }
+
+ this.root = options.root || path.resolve(this.cwd, "/")
+ this.root = path.resolve(this.root)
+ if (process.platform === "win32")
+ this.root = this.root.replace(/\\/g, "/")
+
+ this.nomount = !!options.nomount
+
+ if (!pattern) {
+ throw new Error("must provide pattern")
+ }
+
+ // base-matching: just use globstar for that.
+ if (options.matchBase && -1 === pattern.indexOf("/")) {
+ if (options.noglobstar) {
+ throw new Error("base matching requires globstar")
+ }
+ pattern = "**/" + pattern
+ }
+
+ this.strict = options.strict !== false
+ this.dot = !!options.dot
+ this.mark = !!options.mark
+ this.sync = !!options.sync
+ this.nounique = !!options.nounique
+ this.nonull = !!options.nonull
+ this.nosort = !!options.nosort
+ this.nocase = !!options.nocase
+ this.stat = !!options.stat
+
+ this.debug = !!options.debug || !!options.globDebug
+ if (this.debug)
+ this.log = console.error
+
+ this.silent = !!options.silent
+
+ var mm = this.minimatch = new Minimatch(pattern, options)
+ this.options = mm.options
+ pattern = this.pattern = mm.pattern
+
+ this.error = null
+ this.aborted = false
+
+ // list of all the patterns that ** has resolved do, so
+ // we can avoid visiting multiple times.
+ this._globstars = {}
+
+ EE.call(this)
+
+ // process each pattern in the minimatch set
+ var n = this.minimatch.set.length
+
+ // The matches are stored as {<filename>: true,...} so that
+ // duplicates are automagically pruned.
+ // Later, we do an Object.keys() on these.
+ // Keep them as a list so we can fill in when nonull is set.
+ this.matches = new Array(n)
+
+ this.minimatch.set.forEach(iterator.bind(this))
+ function iterator (pattern, i, set) {
+ this._process(pattern, 0, i, function (er) {
+ if (er) this.emit("error", er)
+ if (-- n <= 0) this._finish()
+ })
+ }
+}
+
+Glob.prototype.log = function () {}
+
+Glob.prototype._finish = function () {
+ assert(this instanceof Glob)
+
+ var nou = this.nounique
+ , all = nou ? [] : {}
+
+ for (var i = 0, l = this.matches.length; i < l; i ++) {
+ var matches = this.matches[i]
+ this.log("matches[%d] =", i, matches)
+ // do like the shell, and spit out the literal glob
+ if (!matches) {
+ if (this.nonull) {
+ var literal = this.minimatch.globSet[i]
+ if (nou) all.push(literal)
+ else all[literal] = true
+ }
+ } else {
+ // had matches
+ var m = Object.keys(matches)
+ if (nou) all.push.apply(all, m)
+ else m.forEach(function (m) {
+ all[m] = true
+ })
+ }
+ }
+
+ if (!nou) all = Object.keys(all)
+
+ if (!this.nosort) {
+ all = all.sort(this.nocase ? alphasorti : alphasort)
+ }
+
+ if (this.mark) {
+ // at *some* point we statted all of these
+ all = all.map(function (m) {
+ var sc = this.cache[m]
+ if (!sc)
+ return m
+ var isDir = (Array.isArray(sc) || sc === 2)
+ if (isDir && m.slice(-1) !== "/") {
+ return m + "/"
+ }
+ if (!isDir && m.slice(-1) === "/") {
+ return m.replace(/\/+$/, "")
+ }
+ return m
+ }, this)
+ }
+
+ this.log("emitting end", all)
+
+ this.EOF = this.found = all
+ this.emitMatch(this.EOF)
+}
+
+function alphasorti (a, b) {
+ a = a.toLowerCase()
+ b = b.toLowerCase()
+ return alphasort(a, b)
+}
+
+function alphasort (a, b) {
+ return a > b ? 1 : a < b ? -1 : 0
+}
+
+Glob.prototype.abort = function () {
+ this.aborted = true
+ this.emit("abort")
+}
+
+Glob.prototype.pause = function () {
+ if (this.paused) return
+ if (this.sync)
+ this.emit("error", new Error("Can't pause/resume sync glob"))
+ this.paused = true
+ this.emit("pause")
+}
+
+Glob.prototype.resume = function () {
+ if (!this.paused) return
+ if (this.sync)
+ this.emit("error", new Error("Can't pause/resume sync glob"))
+ this.paused = false
+ this.emit("resume")
+ this._processEmitQueue()
+ //process.nextTick(this.emit.bind(this, "resume"))
+}
+
+Glob.prototype.emitMatch = function (m) {
+ if (!this.stat || this.statCache[m] || m === this.EOF) {
+ this._emitQueue.push(m)
+ this._processEmitQueue()
+ } else {
+ this._stat(m, function(exists, isDir) {
+ if (exists) {
+ this._emitQueue.push(m)
+ this._processEmitQueue()
+ }
+ })
+ }
+}
+
+Glob.prototype._processEmitQueue = function (m) {
+ while (!this._processingEmitQueue &&
+ !this.paused) {
+ this._processingEmitQueue = true
+ var m = this._emitQueue.shift()
+ if (!m) {
+ this._processingEmitQueue = false
+ break
+ }
+
+ this.log('emit!', m === this.EOF ? "end" : "match")
+
+ this.emit(m === this.EOF ? "end" : "match", m)
+ this._processingEmitQueue = false
+ }
+}
+
+Glob.prototype._process = function (pattern, depth, index, cb_) {
+ assert(this instanceof Glob)
+
+ var cb = function cb (er, res) {
+ assert(this instanceof Glob)
+ if (this.paused) {
+ if (!this._processQueue) {
+ this._processQueue = []
+ this.once("resume", function () {
+ var q = this._processQueue
+ this._processQueue = null
+ q.forEach(function (cb) { cb() })
+ })
+ }
+ this._processQueue.push(cb_.bind(this, er, res))
+ } else {
+ cb_.call(this, er, res)
+ }
+ }.bind(this)
+
+ if (this.aborted) return cb()
+
+ if (depth > this.maxDepth) return cb()
+
+ // Get the first [n] parts of pattern that are all strings.
+ var n = 0
+ while (typeof pattern[n] === "string") {
+ n ++