Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fix jshint dependency

  • Loading branch information...
commit 2c5e377577e2e878635d69b10ea2c240e6032f58 1 parent 718d61a
@russellhaering russellhaering authored
Showing with 6,965 additions and 20,915 deletions.
  1. +0 −3  node_modules/jshint/.gitignore
  2. +0 −3  node_modules/jshint/.gitmodules
  3. +0 −3  node_modules/jshint/.jshintignore
  4. +0 −40 node_modules/jshint/.jshintrc
  5. +0 −9 node_modules/jshint/HELP
  6. +28 −14 node_modules/jshint/README.md
  7. +0 −73 node_modules/jshint/example/config.json
  8. +0 −18 node_modules/jshint/example/reporter.js
  9. +87 −68 node_modules/jshint/lib/cli.js
  10. +12 −8 node_modules/jshint/lib/hint.js
  11. +196 −0 node_modules/jshint/node_modules/cli/README.md
  12. +1,125 −0 node_modules/jshint/node_modules/cli/cli.js
  13. +17 −0 node_modules/jshint/node_modules/cli/examples/cat.js
  14. +16 −0 node_modules/jshint/node_modules/cli/examples/command.js
  15. +54 −0 node_modules/jshint/node_modules/cli/examples/echo.js
  16. +6 −0 node_modules/jshint/node_modules/cli/examples/glob.js
  17. +20 −0 node_modules/jshint/node_modules/cli/examples/long_desc.js
  18. +11 −0 node_modules/jshint/node_modules/cli/examples/progress.js
  19. +18 −0 node_modules/jshint/node_modules/cli/examples/sort.js
  20. +9 −0 node_modules/jshint/node_modules/cli/examples/spinner.js
  21. +27 −0 node_modules/jshint/node_modules/cli/examples/static.coffee
  22. +25 −0 node_modules/jshint/node_modules/cli/examples/static.js
  23. +1 −0  node_modules/jshint/node_modules/cli/index.js
  24. +2 −0  node_modules/jshint/node_modules/cli/node_modules/glob/.npmignore
  25. +4 −0 node_modules/jshint/node_modules/cli/node_modules/glob/.travis.yml
  26. +25 −0 node_modules/jshint/node_modules/cli/node_modules/glob/LICENCE
  27. +233 −0 node_modules/jshint/node_modules/cli/node_modules/glob/README.md
  28. +9 −0 node_modules/jshint/node_modules/cli/node_modules/glob/examples/g.js
  29. +9 −0 node_modules/jshint/node_modules/cli/node_modules/glob/examples/usr-local.js
  30. +601 −0 node_modules/jshint/node_modules/cli/node_modules/glob/glob.js
  31. +1 −0  node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/graceful-fs/.npmignore
  32. +23 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/graceful-fs/LICENSE
  33. +5 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/graceful-fs/README.md
  34. +275 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/graceful-fs/graceful-fs.js
  35. +15 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/graceful-fs/package.json
  36. +51 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/README.md
  37. +29 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/inherits.js
  38. +7 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/package.json
  39. +4 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/.travis.yml
  40. +23 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/LICENSE
  41. +218 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/README.md
  42. +1,052 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/minimatch.js
  43. +1 −0  ..._modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore
  44. +23 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE
  45. +14 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md
  46. +106 −0 ...es/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
  47. +13 −0 ...odules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json
  48. +117 −0 ...dules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js
  49. +29 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/package.json
  50. +273 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/test/basic.js
  51. +33 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/test/brace-expand.js
  52. +14 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/test/caching.js
  53. +274 −0 node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/minimatch/test/defaults.js
  54. +28 −0 node_modules/jshint/node_modules/cli/node_modules/glob/package.json
  55. +61 −0 node_modules/jshint/node_modules/cli/node_modules/glob/test/00-setup.js
  56. +119 −0 node_modules/jshint/node_modules/cli/node_modules/glob/test/bash-comparison.js
  57. +55 −0 node_modules/jshint/node_modules/cli/node_modules/glob/test/cwd-test.js
  58. +98 −0 node_modules/jshint/node_modules/cli/node_modules/glob/test/pause-resume.js
  59. +39 −0 node_modules/jshint/node_modules/cli/node_modules/glob/test/root-nomount.js
  60. +43 −0 node_modules/jshint/node_modules/cli/node_modules/glob/test/root.js
  61. +11 −0 node_modules/jshint/node_modules/cli/node_modules/glob/test/zz-cleanup.js
  62. +26 −0 node_modules/jshint/node_modules/cli/package.json
  63. +4 −0 node_modules/jshint/node_modules/minimatch/.travis.yml
  64. +23 −0 node_modules/jshint/node_modules/minimatch/LICENSE
  65. +114 −0 node_modules/jshint/node_modules/minimatch/README.md
  66. +62 −0 node_modules/jshint/node_modules/minimatch/blerg.js
  67. +372 −0 node_modules/jshint/node_modules/minimatch/minimatch.js
  68. +1 −0  node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/.npmignore
  69. +23 −0 node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/LICENSE
  70. +14 −0 node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/README.md
  71. +106 −0 node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
  72. +13 −0 node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/package.json
  73. +117 −0 node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/test/basic.js
  74. +29 −0 node_modules/jshint/node_modules/minimatch/package.json
  75. +4 −0 node_modules/jshint/node_modules/minimatch/t.js
  76. +167 −0 node_modules/jshint/node_modules/minimatch/test/basic.js
  77. +4 −5 node_modules/jshint/package.json
  78. +0 −1  node_modules/jshint/packages/jshint/.gitignore
  79. +0 −63 node_modules/jshint/packages/jshint/CHANGELOG
  80. +0 −16 node_modules/jshint/packages/jshint/Makefile
  81. +8 −7 node_modules/jshint/packages/jshint/README.markdown
  82. +0 −57 node_modules/jshint/packages/jshint/env/jsc.js
  83. +0 −29 node_modules/jshint/packages/jshint/env/jsc.sh
  84. +0 −75 node_modules/jshint/packages/jshint/env/rhino.js
  85. +0 −168 node_modules/jshint/packages/jshint/env/wsh.js
  86. +288 −76 node_modules/jshint/packages/jshint/jshint.js
  87. +0 −401 node_modules/jshint/packages/jshint/tests/core.js
  88. +0 −514 node_modules/jshint/packages/jshint/tests/envs.js
  89. +0 −28 node_modules/jshint/packages/jshint/tests/fixtures/asi.js
  90. +0 −1,158 node_modules/jshint/packages/jshint/tests/fixtures/backbone.js
  91. +0 −12 node_modules/jshint/packages/jshint/tests/fixtures/boss.js
  92. +0 −11 node_modules/jshint/packages/jshint/tests/fixtures/caseExpressions.js
  93. +0 −72 node_modules/jshint/packages/jshint/tests/fixtures/const.js
  94. +0 −8 node_modules/jshint/packages/jshint/tests/fixtures/curly.js
  95. +0 −11 node_modules/jshint/packages/jshint/tests/fixtures/curly2.js
  96. +0 −23 node_modules/jshint/packages/jshint/tests/fixtures/emptystmt.js
  97. +0 −10 node_modules/jshint/packages/jshint/tests/fixtures/eqeqeq.js
  98. +0 −15 node_modules/jshint/packages/jshint/tests/fixtures/es5.funcexpr.js
  99. +0 −38 node_modules/jshint/packages/jshint/tests/fixtures/es5.js
  100. +0 −15 node_modules/jshint/packages/jshint/tests/fixtures/forin.js
  101. +0 −8 node_modules/jshint/packages/jshint/tests/fixtures/functionScopedOptions.js
  102. +0 −15 node_modules/jshint/packages/jshint/tests/fixtures/immed.js
  103. +0 −8 node_modules/jshint/packages/jshint/tests/fixtures/indent.js
  104. +0 −9,304 node_modules/jshint/packages/jshint/tests/fixtures/jquery-1.7.js
  105. +0 −9 node_modules/jshint/packages/jshint/tests/fixtures/jslintOptions.js
  106. +0 −6 node_modules/jshint/packages/jshint/tests/fixtures/lastsemic.js
  107. +0 −11 node_modules/jshint/packages/jshint/tests/fixtures/latedef.js
  108. +0 −46 node_modules/jshint/packages/jshint/tests/fixtures/latedefundef.js
  109. +0 −19 node_modules/jshint/packages/jshint/tests/fixtures/laxbreak.js
  110. +0 −11 node_modules/jshint/packages/jshint/tests/fixtures/loopfunc.js
  111. +0 −3  node_modules/jshint/packages/jshint/tests/fixtures/maxlen.js
  112. +0 −8 node_modules/jshint/packages/jshint/tests/fixtures/missingspaces.js
  113. +0 −5 node_modules/jshint/packages/jshint/tests/fixtures/newcap.js
  114. +0 −7 node_modules/jshint/packages/jshint/tests/fixtures/noarg.js
  115. +0 −11 node_modules/jshint/packages/jshint/tests/fixtures/onevar.js
  116. +0 −37 node_modules/jshint/packages/jshint/tests/fixtures/protoiterator.js
  117. +0 −6,082 node_modules/jshint/packages/jshint/tests/fixtures/prototype-17.js
  118. +0 −11 node_modules/jshint/packages/jshint/tests/fixtures/redef.js
  119. +0 −40 node_modules/jshint/packages/jshint/tests/fixtures/return.js
  120. +0 −43 node_modules/jshint/packages/jshint/tests/fixtures/scope.js
  121. +0 −11 node_modules/jshint/packages/jshint/tests/fixtures/scripturl.js
  122. +0 −7 node_modules/jshint/packages/jshint/tests/fixtures/smarttabs.js
  123. +0 −59 node_modules/jshint/packages/jshint/tests/fixtures/strict_incorrect.js
  124. +0 −17 node_modules/jshint/packages/jshint/tests/fixtures/strict_this.js
  125. +0 −18 node_modules/jshint/packages/jshint/tests/fixtures/strict_this2.js
  126. +0 −9 node_modules/jshint/packages/jshint/tests/fixtures/strict_violations.js
  127. +0 −16 node_modules/jshint/packages/jshint/tests/fixtures/strings.js
  128. +0 −11 node_modules/jshint/packages/jshint/tests/fixtures/supernew.js
  129. +0 −40 node_modules/jshint/packages/jshint/tests/fixtures/switchFallThrough.js
  130. +0 −24 node_modules/jshint/packages/jshint/tests/fixtures/trycatch.js
  131. +0 −10 node_modules/jshint/packages/jshint/tests/fixtures/undef.js
  132. +0 −6 node_modules/jshint/packages/jshint/tests/fixtures/undefstrict.js
  133. +0 −66 node_modules/jshint/packages/jshint/tests/fixtures/white.js
  134. +0 −1,007 node_modules/jshint/packages/jshint/tests/options.js
  135. +0 −318 node_modules/jshint/packages/jshint/tests/parser.js
  136. +0 −147 node_modules/jshint/packages/jshint/tests/testhelper
  137. +0 −20 node_modules/jshint/test/system/genfiles
  138. +0 −34 node_modules/jshint/test/system/perf.js
  139. +0 −185 node_modules/jshint/test/unit/cli.js
  140. +0 −174 node_modules/jshint/test/unit/hint.js
  141. +1 −0  package.json
View
3  node_modules/jshint/.gitignore
@@ -1,3 +0,0 @@
-tags
-node_modules
-test/system/.files
View
3  node_modules/jshint/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "packages/jshint"]
- path = packages/jshint
- url = git://github.com/jshint/jshint.git
View
3  node_modules/jshint/.jshintignore
@@ -1,3 +0,0 @@
-node_modules
-packages
-.git
View
40 node_modules/jshint/.jshintrc
@@ -1,40 +0,0 @@
-{
- "predef": [
- "jasmine",
- "spyOn",
- "it",
- "console",
- "describe",
- "expect",
- "beforeEach",
- "waits",
- "waitsFor",
- "runs"
- ],
-
- "node" : true,
- "es5" : true,
- "browser" : true,
-
- "boss" : false,
- "curly": false,
- "debug": false,
- "devel": false,
- "eqeqeq": true,
- "evil": true,
- "forin": false,
- "immed": true,
- "laxbreak": false,
- "newcap": true,
- "noarg": true,
- "noempty": false,
- "nonew": false,
- "nomen": false,
- "onevar": true,
- "plusplus": false,
- "regexp": false,
- "undef": true,
- "sub": true,
- "strict": false,
- "white": true
-}
View
9 node_modules/jshint/HELP
@@ -1,9 +0,0 @@
-Usage: jshint path path2 [options]
-
-Options:
-
- --version display package version
- --config custom config file
- --reporter custom reporter
- --jslint-reporter use a jslint compatible xml reporter
- --show-non-errors show additional data generated by jshint
View
42 node_modules/jshint/README.md
@@ -4,15 +4,13 @@ A command line interface and npm package for jshint.
## Install
-To use jshint from any location (for npm v1.x) you need to install using the global (-g) flag.
+To use jshint from any location (for npm v1.x) you need to install using the global (-g) flag.
npm install -g jshint
## Usage
-The command line interface looks like this.
-
- jshint path path2 [options]
+ jshint -h
You can also require JSHint itself as a module.
@@ -24,6 +22,7 @@ Note: If you are using npm v1.x be sure to install jshint locally (without the -
* [gedit-node-jshint](https://github.com/niftylettuce/gedit-node-jshint) - Simply use CTRL+J in gedit to run JSHint using `node-jshint`.
* [vim syntastic](https://github.com/scrooloose/syntastic) - Run node-jshint at each file save.
+* [sublime-jshint](https://github.com/uipoet/sublime-jshint) - `F7` or `command-B` on any .js file. `F4` next error line,column. `shift-F4` previous error line,column.
## Custom Reporters
@@ -39,27 +38,37 @@ Show additional non-error data generated by jshint (unused globals etc).
--show-non-errors
-## Custom Options
+## Configuration Options
+
+**Note:** This behavior described below is very different from versions prior to `0.6`.
+
+The CLI uses the default options that come with JSHint. To have your own configuration apply, there are several methods you can use:
+
+### Specify Manually
-Specify custom lint options (see [example/config.json](https://github.com/jshint/node-jshint/blob/master/example/config.json)).
+Setting the `--config=/path/to/your/config` command line option to specify your own configuration file outside of the directory tree for your project.
- --config path/to/config.json
+### Within your Project's Directory Tree
-Note: This bypasses any .jshintrc files.
+When the CLI is called, and a configuration file isn't specified already, `node-jshint` will attempt to locate one for you starting in `pwd`. (or "present working directory") If this does not yield a `.jshintrc` file, it will move one level up (`..`) the directory tree all the way up to the filesystem root. If a file is found, it stops immediately and uses that set of configuration.
-## Default Options
+This setup allows you to set up **one** configuration file for your entire project. (place it in the root folder) As long as you run `jshint` from anywhere within your project directory tree, the same configuration file will be used.
-The CLI uses the default options that come with JSHint. However, if it locates a .jshintrc file in your home directory (~/) it will use those options first.
+### Home Directory
-## Per Directory Options
+If all the methods above do not yield a `.jshintrc` to use, the last place that will be checked is your user's `$HOME` directory.
-If there is a .jshintrc file in the current working directory, any of those options will take precedence over (or be merged with) any options found in the ~/.jshintrc file (if it exists).
+## File Extensions
+
+Default extension for files is ".js". If you want to use JSHint with other file extensions (.json), you need to pass this extra extension as an option :
+
+ --extra-ext .json
## Ignoring Files and Directories
-If there is a .jshintignore file in the current working directory, then any directories or files will be skipped over.
+If there is a .jshintignore file in your project's directory tree, (also provided you run `jshint` from within your project's directory) then any directories or files specified will be skipped over. (behaves just like a `.gitignore` file)
-Note: Pattern matching uses minimatch, with the nocase [option](https://github.com/isaacs/minimatch). When there is no match, it performs a left side match (when no forward slashes present and path is a directory).
+**Note:** Pattern matching uses minimatch, with the nocase [option](https://github.com/isaacs/minimatch). When there is no match, it performs a left side match (when no forward slashes present and path is a directory).
## Installing dependencies for development
@@ -68,3 +77,8 @@ Note: Pattern matching uses minimatch, with the nocase [option](https://github.c
## Build Commands
jake -T
+
+## Project Guidelines
+
+* All tests are passing.
+* No (new) JSHint errors are introduced.
View
73 node_modules/jshint/example/config.json
@@ -1,73 +0,0 @@
-{
- // Settings
- "passfail" : false, // Stop on first error.
- "maxerr" : 100, // Maximum error before stopping.
-
-
- // Predefined globals whom JSHint will ignore.
- "browser" : true, // Standard browser globals e.g. `window`, `document`.
-
- "node" : false,
- "rhino" : false,
- "couch" : false,
- "wsh" : true, // Windows Scripting Host.
-
- "jquery" : true,
- "prototypejs" : false,
- "mootools" : false,
- "dojo" : false,
-
- "predef" : [ // Custom globals.
- //"exampleVar",
- //"anotherCoolGlobal",
- //"iLoveDouglas"
- ],
-
-
- // Development.
- "debug" : false, // Allow debugger statements e.g. browser breakpoints.
- "devel" : true, // Allow developments statements e.g. `console.log();`.
-
-
- // ECMAScript 5.
- "es5" : true, // Allow ECMAScript 5 syntax.
- "strict" : false, // Require `use strict` pragma in every file.
- "globalstrict" : false, // Allow global "use strict" (also enables 'strict').
-
-
- // The Good Parts.
- "asi" : false, // Tolerate Automatic Semicolon Insertion (no semicolons).
- "laxbreak" : true, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons.
- "bitwise" : true, // Prohibit bitwise operators (&, |, ^, etc.).
- "boss" : false, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments.
- "curly" : true, // Require {} for every new block or scope.
- "eqeqeq" : true, // Require triple equals i.e. `===`.
- "eqnull" : false, // Tolerate use of `== null`.
- "evil" : false, // Tolerate use of `eval`.
- "expr" : false, // Tolerate `ExpressionStatement` as Programs.
- "forin" : false, // Tolerate `for in` loops without `hasOwnPrototype`.
- "immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
- "latedef" : true, // Prohipit variable use before definition.
- "loopfunc" : false, // Allow functions to be defined within loops.
- "noarg" : true, // Prohibit use of `arguments.caller` and `arguments.callee`.
- "regexp" : true, // Prohibit `.` and `[^...]` in regular expressions.
- "regexdash" : false, // Tolerate unescaped last dash i.e. `[-...]`.
- "scripturl" : true, // Tolerate script-targeted URLs.
- "shadow" : false, // Allows re-define variables later in code e.g. `var x=1; x=2;`.
- "supernew" : false, // Tolerate `new function () { ... };` and `new Object;`.
- "undef" : true, // Require all non-global variables be declared before they are used.
-
-
- // Personal styling preferences.
- "newcap" : true, // Require capitalization of all constructor functions e.g. `new F()`.
- "noempty" : true, // Prohibit use of empty blocks.
- "nonew" : true, // Prohibit use of constructors for side-effects.
- "nomen" : true, // Prohibit use of initial or trailing underbars in names.
- "onevar" : false, // Allow only one `var` statement per function.
- "plusplus" : false, // Prohibit use of `++` & `--`.
- "sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`.
- "trailing" : true, // Prohibit trailing whitespaces.
- "white" : true, // Check against strict whitespace and indentation rules.
- "indent" : 4 // Specify indentation spacing
-}
-
View
18 node_modules/jshint/example/reporter.js
@@ -1,18 +0,0 @@
-module.exports = {
- reporter: function reporter(results) {
- var len = results.length,
- str = '',
- file, error;
-
- results.forEach(function (result) {
- file = result.file;
- error = result.error;
- str += file + ': line ' + error.line + ', col ' +
- error.character + ', ' + error.reason + '\n';
- });
-
- if (str) {
- process.stdout.write(str + "\n" + len + ' error' + ((len === 1) ? '' : 's') + "\n");
- }
- }
-};
View
155 node_modules/jshint/lib/cli.js
@@ -1,44 +1,69 @@
var fs = require('fs'),
path = require('path'),
- argsparser = require('argsparser'),
+ cli = require('cli').enable('glob', 'help'),
hint = require('./hint');
-function _help() {
- process.stdout.write(fs.readFileSync(__dirname + "/../HELP", "utf-8"));
-}
-
-function _version() {
- process.stdout.write(JSON.parse(fs.readFileSync(__dirname + "/../package.json", "utf-8")).version + "\n");
+function existsSync() {
+ var obj = fs.existsSync ? fs : path;
+ return obj.existsSync.apply(obj, arguments);
}
function _removeJsComments(str) {
str = str || '';
- str = str.replace(/\/\*[\s\S]*(?:\*\/)/g, ''); //everything between "/* */"
+
+ // replace everything between "/* */" in a non-greedy way
+ // The English version of the regex is:
+ // match '/*'
+ // then match 0 or more instances of any character (including newlines)
+ // except for instances of '*/'
+ // then match '*/'
+ str = str.replace(/\/\*(?:(?!\*\/)[\s\S])*\*\//g, '');
+
str = str.replace(/\/\/[^\n\r]*/g, ''); //everything after "//"
return str;
}
function _loadAndParseConfig(filePath) {
- return path.existsSync(filePath) ?
+ return filePath && existsSync(filePath) ?
JSON.parse(_removeJsComments(fs.readFileSync(filePath, "utf-8"))) : {};
}
-function _mergeConfigs(homerc, cwdrc) {
- var homeConfig = _loadAndParseConfig(homerc),
- cwdConfig = _loadAndParseConfig(cwdrc),
- prop;
-
- for (prop in cwdConfig) {
- if (typeof prop === 'string') {
- if (prop === 'predef') {
- homeConfig.predef = (homeConfig.predef || []).concat(cwdConfig.predef);
- } else {
- homeConfig[prop] = cwdConfig[prop];
- }
- }
+/**
+ * This function searches for a file with a specified name, it starts
+ * with the dir passed, and traverses up the filesystem until it either
+ * finds the file, or hits the root
+ *
+ * @param {String} name Filename to search for (.jshintrc, .jshintignore)
+ * @param {String} dir Defaults to process.cwd()
+ */
+function _searchFile(name, dir) {
+ dir = dir || process.cwd();
+
+ var filename = path.normalize(path.join(dir, name)),
+ parent = path.resolve(dir, "..");
+
+ if (existsSync(filename)) {
+ return filename;
}
- return homeConfig;
+ return dir === parent ? null : _searchFile(name, parent);
+}
+
+function _findConfig(target) {
+ var name = ".jshintrc",
+ projectConfig = _searchFile(name),
+ homeConfig = path.normalize(path.join(process.env.HOME, name));
+
+ if (projectConfig) {
+ return projectConfig;
+ }
+
+ // if no project config, check $HOME
+ if (existsSync(homeConfig)) {
+ return homeConfig;
+ }
+
+ return false;
}
function _print(results) {
@@ -61,55 +86,46 @@ function _print(results) {
module.exports = {
interpret: function (args) {
- var config, reporter, ignore,
- options = argsparser.parse(args),
- pathsToIgnore = path.join(process.cwd(), '.jshintignore'),
- defaultConfig = path.join(process.env.HOME, '.jshintrc'),
- projectConfig = path.join(process.cwd(), '.jshintrc'),
- customConfig = options["--config"],
- customReporter = options["--reporter"] ? path.resolve(process.cwd(), options["--reporter"]) : null,
- targets = options.node;
-
- //could be on Windows which we are looking for an attribute ending in 'node.exe'
- if (targets === undefined) {
- (function () {
- var arg;
-
- for (arg in options) {
- if (path.basename(arg) === 'node.exe') {
- targets = options[arg];
- break;
- }
- }
- }());
- }
-
- targets = typeof targets === "string" ? null : targets.slice(1);
-
-
- if (options["--version"]) {
- _version();
+ var config, reporter, options,
+ customConfig, customReporter,
+ ignoreFile, ignores, extraExtensionList;
+
+ cli.setArgv(args);
+ cli.options = {};
+ options = cli.parse({
+ 'version': ['v', 'display package version', 'boolean', false],
+ 'config': ['config', 'custom config file', 'string', false],
+ 'reporter': ['reporter', 'custom reporter', 'string', undefined],
+ 'jslint-reporter': ['jslint-reporter', 'use a jslint compatible xml reporter'],
+ 'show-non-errors': ['show-non-errors', 'show additional data generated by jshint'],
+ 'extra-ext': ['extra-ext', 'comma-separated list of file extensions to use (.js is default)', 'string', '']
+ });
+
+ customConfig = options.config;
+ customReporter = options.reporter ? path.resolve(process.cwd(), options.reporter) : null;
+ extraExtensionList = options["extra-ext"];
+
+ if (options.version) {
+ cli.setApp(path.resolve(__dirname + "/../package.json"));
+ process.stdout.write(cli.version + "\n");
return;
}
- if (!targets || options["--help"]) {
- _help();
+ if (options.help || !cli.args.length) {
+ cli.getUsage();
+ process.exit();
return;
}
- if (options["--jslint-reporter"]) {
+ if (options['jslint-reporter']) {
customReporter = "./reporters/jslint_xml.js";
}
- if (options["--show-non-errors"]) {
+ if (options['show-non-errors']) {
customReporter = "./reporters/non_error.js";
}
- if (customConfig) {
- config = _loadAndParseConfig(customConfig);
- } else {
- config = _mergeConfigs(defaultConfig, projectConfig);
- }
+ config = _loadAndParseConfig(customConfig ? customConfig : _findConfig());
if (customReporter) {
try {
@@ -121,15 +137,18 @@ module.exports = {
}
}
- if (path.existsSync(pathsToIgnore)) {
- ignore = fs.readFileSync(pathsToIgnore, "utf-8").split("\n").map(function (line) {
- return line.trim();
- }).filter(function (line) {
- return !!line;
- });
+ ignoreFile = _searchFile(".jshintignore");
+
+ if (ignoreFile) {
+ ignores = fs.readFileSync(ignoreFile, "utf8").split("\n")
+ .filter(function (line) {
+ return !!line.trim();
+ })
+ .map(function (line) {
+ return path.resolve(path.dirname(ignoreFile), line.trim());
+ });
}
- _print(hint.hint(targets, config, reporter, ignore));
+ _print(hint.hint(cli.args, config, reporter, ignores, extraExtensionList));
}
};
-
View
20 node_modules/jshint/lib/hint.js
@@ -58,10 +58,11 @@ function isDirectory(aPath) {
function _shouldIgnore(somePath, ignore) {
function isIgnored(p) {
var fnmatch = minimatch(somePath, p, {nocase: true}),
+ absmatch = path.resolve(somePath) === p,
lsmatch = isDirectory(p) && p.match(/^[^\/]*\/?$/) &&
somePath.match(new RegExp("^" + p + ".*"));
- return !!(fnmatch || lsmatch);
+ return !!(fnmatch || lsmatch || absmatch);
}
return ignore.some(function (ignorePath) {
@@ -69,28 +70,31 @@ function _shouldIgnore(somePath, ignore) {
});
}
-function _collect(filePath, files, ignore) {
+function _collect(filePath, files, ignore, regExtension) {
if (ignore && _shouldIgnore(filePath, ignore)) {
return;
}
-
if (fs.statSync(filePath).isDirectory()) {
fs.readdirSync(filePath).forEach(function (item) {
- _collect(path.join(filePath, item), files, ignore);
+ _collect(path.join(filePath, item), files, ignore, regExtension);
});
- } else if (filePath.match(/\.js$/)) {
+ } else if (filePath.match(regExtension)) {
files.push(filePath);
}
}
module.exports = {
- hint: function (targets, config, reporter, ignore) {
+ hint: function (targets, config, reporter, ignore, extraExtensionList) {
var files = [],
results = [],
- data = [];
+ data = [],
+ regExtension;
+
+ extraExtensionList = extraExtensionList || "";
+ regExtension = new RegExp('\\.(js' + (extraExtensionList === "" ? "" : "|" + extraExtensionList.replace(/,/g, "|").replace(/[\. ]/g, "")) + ")$");
targets.forEach(function (target) {
- _collect(target, files, ignore);
+ _collect(target, files, ignore, regExtension);
});
files.forEach(function (file) {
View
196 node_modules/jshint/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,125 node_modules/jshint/node_modules/cli/cli.js
@@ -0,0 +1,1125 @@
+/**
+ * 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.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][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);
+ }
+ 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) {
+ if (progress < 0 || progress > 1 || isNaN(progress)) return;
+ 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 ? '#' : ' ';
+ }
+ cli.native.util.print('[' + str + '] ' + Math.floor(progress * 100) + '%' + (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 node_modules/jshint/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 node_modules/jshint/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 node_modules/jshint/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 node_modules/jshint/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 node_modules/jshint/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 node_modules/jshint/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 node_modules/jshint/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 node_modules/jshint/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 node_modules/jshint/node_modules/cli/examples/static.coffee
@@ -0,0 +1,27 @@
+#!/usr/bin/env coffee
+
+cli = require 'cli'
+