Security update to Drupal 8.4.6
[yaffs-website] / node_modules / commander / index.js
1 /**
2  * Module dependencies.
3  */
4
5 var EventEmitter = require('events').EventEmitter;
6 var spawn = require('child_process').spawn;
7 var readlink = require('graceful-readlink').readlinkSync;
8 var path = require('path');
9 var dirname = path.dirname;
10 var basename = path.basename;
11 var fs = require('fs');
12
13 /**
14  * Expose the root command.
15  */
16
17 exports = module.exports = new Command();
18
19 /**
20  * Expose `Command`.
21  */
22
23 exports.Command = Command;
24
25 /**
26  * Expose `Option`.
27  */
28
29 exports.Option = Option;
30
31 /**
32  * Initialize a new `Option` with the given `flags` and `description`.
33  *
34  * @param {String} flags
35  * @param {String} description
36  * @api public
37  */
38
39 function Option(flags, description) {
40   this.flags = flags;
41   this.required = ~flags.indexOf('<');
42   this.optional = ~flags.indexOf('[');
43   this.bool = !~flags.indexOf('-no-');
44   flags = flags.split(/[ ,|]+/);
45   if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift();
46   this.long = flags.shift();
47   this.description = description || '';
48 }
49
50 /**
51  * Return option name.
52  *
53  * @return {String}
54  * @api private
55  */
56
57 Option.prototype.name = function() {
58   return this.long
59     .replace('--', '')
60     .replace('no-', '');
61 };
62
63 /**
64  * Check if `arg` matches the short or long flag.
65  *
66  * @param {String} arg
67  * @return {Boolean}
68  * @api private
69  */
70
71 Option.prototype.is = function(arg) {
72   return arg == this.short || arg == this.long;
73 };
74
75 /**
76  * Initialize a new `Command`.
77  *
78  * @param {String} name
79  * @api public
80  */
81
82 function Command(name) {
83   this.commands = [];
84   this.options = [];
85   this._execs = {};
86   this._allowUnknownOption = false;
87   this._args = [];
88   this._name = name || '';
89 }
90
91 /**
92  * Inherit from `EventEmitter.prototype`.
93  */
94
95 Command.prototype.__proto__ = EventEmitter.prototype;
96
97 /**
98  * Add command `name`.
99  *
100  * The `.action()` callback is invoked when the
101  * command `name` is specified via __ARGV__,
102  * and the remaining arguments are applied to the
103  * function for access.
104  *
105  * When the `name` is "*" an un-matched command
106  * will be passed as the first arg, followed by
107  * the rest of __ARGV__ remaining.
108  *
109  * Examples:
110  *
111  *      program
112  *        .version('0.0.1')
113  *        .option('-C, --chdir <path>', 'change the working directory')
114  *        .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
115  *        .option('-T, --no-tests', 'ignore test hook')
116  *
117  *      program
118  *        .command('setup')
119  *        .description('run remote setup commands')
120  *        .action(function() {
121  *          console.log('setup');
122  *        });
123  *
124  *      program
125  *        .command('exec <cmd>')
126  *        .description('run the given remote command')
127  *        .action(function(cmd) {
128  *          console.log('exec "%s"', cmd);
129  *        });
130  *
131  *      program
132  *        .command('teardown <dir> [otherDirs...]')
133  *        .description('run teardown commands')
134  *        .action(function(dir, otherDirs) {
135  *          console.log('dir "%s"', dir);
136  *          if (otherDirs) {
137  *            otherDirs.forEach(function (oDir) {
138  *              console.log('dir "%s"', oDir);
139  *            });
140  *          }
141  *        });
142  *
143  *      program
144  *        .command('*')
145  *        .description('deploy the given env')
146  *        .action(function(env) {
147  *          console.log('deploying "%s"', env);
148  *        });
149  *
150  *      program.parse(process.argv);
151   *
152  * @param {String} name
153  * @param {String} [desc] for git-style sub-commands
154  * @return {Command} the new command
155  * @api public
156  */
157
158 Command.prototype.command = function(name, desc, opts) {
159   opts = opts || {};
160   var args = name.split(/ +/);
161   var cmd = new Command(args.shift());
162
163   if (desc) {
164     cmd.description(desc);
165     this.executables = true;
166     this._execs[cmd._name] = true;
167     if (opts.isDefault) this.defaultExecutable = cmd._name;
168   }
169
170   cmd._noHelp = !!opts.noHelp;
171   this.commands.push(cmd);
172   cmd.parseExpectedArgs(args);
173   cmd.parent = this;
174
175   if (desc) return this;
176   return cmd;
177 };
178
179 /**
180  * Define argument syntax for the top-level command.
181  *
182  * @api public
183  */
184
185 Command.prototype.arguments = function (desc) {
186   return this.parseExpectedArgs(desc.split(/ +/));
187 };
188
189 /**
190  * Add an implicit `help [cmd]` subcommand
191  * which invokes `--help` for the given command.
192  *
193  * @api private
194  */
195
196 Command.prototype.addImplicitHelpCommand = function() {
197   this.command('help [cmd]', 'display help for [cmd]');
198 };
199
200 /**
201  * Parse expected `args`.
202  *
203  * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`.
204  *
205  * @param {Array} args
206  * @return {Command} for chaining
207  * @api public
208  */
209
210 Command.prototype.parseExpectedArgs = function(args) {
211   if (!args.length) return;
212   var self = this;
213   args.forEach(function(arg) {
214     var argDetails = {
215       required: false,
216       name: '',
217       variadic: false
218     };
219
220     switch (arg[0]) {
221       case '<':
222         argDetails.required = true;
223         argDetails.name = arg.slice(1, -1);
224         break;
225       case '[':
226         argDetails.name = arg.slice(1, -1);
227         break;
228     }
229
230     if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') {
231       argDetails.variadic = true;
232       argDetails.name = argDetails.name.slice(0, -3);
233     }
234     if (argDetails.name) {
235       self._args.push(argDetails);
236     }
237   });
238   return this;
239 };
240
241 /**
242  * Register callback `fn` for the command.
243  *
244  * Examples:
245  *
246  *      program
247  *        .command('help')
248  *        .description('display verbose help')
249  *        .action(function() {
250  *           // output help here
251  *        });
252  *
253  * @param {Function} fn
254  * @return {Command} for chaining
255  * @api public
256  */
257
258 Command.prototype.action = function(fn) {
259   var self = this;
260   var listener = function(args, unknown) {
261     // Parse any so-far unknown options
262     args = args || [];
263     unknown = unknown || [];
264
265     var parsed = self.parseOptions(unknown);
266
267     // Output help if necessary
268     outputHelpIfNecessary(self, parsed.unknown);
269
270     // If there are still any unknown options, then we simply
271     // die, unless someone asked for help, in which case we give it
272     // to them, and then we die.
273     if (parsed.unknown.length > 0) {
274       self.unknownOption(parsed.unknown[0]);
275     }
276
277     // Leftover arguments need to be pushed back. Fixes issue #56
278     if (parsed.args.length) args = parsed.args.concat(args);
279
280     self._args.forEach(function(arg, i) {
281       if (arg.required && null == args[i]) {
282         self.missingArgument(arg.name);
283       } else if (arg.variadic) {
284         if (i !== self._args.length - 1) {
285           self.variadicArgNotLast(arg.name);
286         }
287
288         args[i] = args.splice(i);
289       }
290     });
291
292     // Always append ourselves to the end of the arguments,
293     // to make sure we match the number of arguments the user
294     // expects
295     if (self._args.length) {
296       args[self._args.length] = self;
297     } else {
298       args.push(self);
299     }
300
301     fn.apply(self, args);
302   };
303   var parent = this.parent || this;
304   var name = parent === this ? '*' : this._name;
305   parent.on(name, listener);
306   if (this._alias) parent.on(this._alias, listener);
307   return this;
308 };
309
310 /**
311  * Define option with `flags`, `description` and optional
312  * coercion `fn`.
313  *
314  * The `flags` string should contain both the short and long flags,
315  * separated by comma, a pipe or space. The following are all valid
316  * all will output this way when `--help` is used.
317  *
318  *    "-p, --pepper"
319  *    "-p|--pepper"
320  *    "-p --pepper"
321  *
322  * Examples:
323  *
324  *     // simple boolean defaulting to false
325  *     program.option('-p, --pepper', 'add pepper');
326  *
327  *     --pepper
328  *     program.pepper
329  *     // => Boolean
330  *
331  *     // simple boolean defaulting to true
332  *     program.option('-C, --no-cheese', 'remove cheese');
333  *
334  *     program.cheese
335  *     // => true
336  *
337  *     --no-cheese
338  *     program.cheese
339  *     // => false
340  *
341  *     // required argument
342  *     program.option('-C, --chdir <path>', 'change the working directory');
343  *
344  *     --chdir /tmp
345  *     program.chdir
346  *     // => "/tmp"
347  *
348  *     // optional argument
349  *     program.option('-c, --cheese [type]', 'add cheese [marble]');
350  *
351  * @param {String} flags
352  * @param {String} description
353  * @param {Function|Mixed} fn or default
354  * @param {Mixed} defaultValue
355  * @return {Command} for chaining
356  * @api public
357  */
358
359 Command.prototype.option = function(flags, description, fn, defaultValue) {
360   var self = this
361     , option = new Option(flags, description)
362     , oname = option.name()
363     , name = camelcase(oname);
364
365   // default as 3rd arg
366   if (typeof fn != 'function') {
367     if (fn instanceof RegExp) {
368       var regex = fn;
369       fn = function(val, def) {
370         var m = regex.exec(val);
371         return m ? m[0] : def;
372       }
373     }
374     else {
375       defaultValue = fn;
376       fn = null;
377     }
378   }
379
380   // preassign default value only for --no-*, [optional], or <required>
381   if (false == option.bool || option.optional || option.required) {
382     // when --no-* we make sure default is true
383     if (false == option.bool) defaultValue = true;
384     // preassign only if we have a default
385     if (undefined !== defaultValue) self[name] = defaultValue;
386   }
387
388   // register the option
389   this.options.push(option);
390
391   // when it's passed assign the value
392   // and conditionally invoke the callback
393   this.on(oname, function(val) {
394     // coercion
395     if (null !== val && fn) val = fn(val, undefined === self[name]
396       ? defaultValue
397       : self[name]);
398
399     // unassigned or bool
400     if ('boolean' == typeof self[name] || 'undefined' == typeof self[name]) {
401       // if no value, bool true, and we have a default, then use it!
402       if (null == val) {
403         self[name] = option.bool
404           ? defaultValue || true
405           : false;
406       } else {
407         self[name] = val;
408       }
409     } else if (null !== val) {
410       // reassign
411       self[name] = val;
412     }
413   });
414
415   return this;
416 };
417
418 /**
419  * Allow unknown options on the command line.
420  *
421  * @param {Boolean} arg if `true` or omitted, no error will be thrown
422  * for unknown options.
423  * @api public
424  */
425 Command.prototype.allowUnknownOption = function(arg) {
426     this._allowUnknownOption = arguments.length === 0 || arg;
427     return this;
428 };
429
430 /**
431  * Parse `argv`, settings options and invoking commands when defined.
432  *
433  * @param {Array} argv
434  * @return {Command} for chaining
435  * @api public
436  */
437
438 Command.prototype.parse = function(argv) {
439   // implicit help
440   if (this.executables) this.addImplicitHelpCommand();
441
442   // store raw args
443   this.rawArgs = argv;
444
445   // guess name
446   this._name = this._name || basename(argv[1], '.js');
447
448   // github-style sub-commands with no sub-command
449   if (this.executables && argv.length < 3 && !this.defaultExecutable) {
450     // this user needs help
451     argv.push('--help');
452   }
453
454   // process argv
455   var parsed = this.parseOptions(this.normalize(argv.slice(2)));
456   var args = this.args = parsed.args;
457
458   var result = this.parseArgs(this.args, parsed.unknown);
459
460   // executable sub-commands
461   var name = result.args[0];
462   if (this._execs[name] && typeof this._execs[name] != "function") {
463     return this.executeSubCommand(argv, args, parsed.unknown);
464   } else if (this.defaultExecutable) {
465     // use the default subcommand
466     args.unshift(name = this.defaultExecutable);
467     return this.executeSubCommand(argv, args, parsed.unknown);
468   }
469
470   return result;
471 };
472
473 /**
474  * Execute a sub-command executable.
475  *
476  * @param {Array} argv
477  * @param {Array} args
478  * @param {Array} unknown
479  * @api private
480  */
481
482 Command.prototype.executeSubCommand = function(argv, args, unknown) {
483   args = args.concat(unknown);
484
485   if (!args.length) this.help();
486   if ('help' == args[0] && 1 == args.length) this.help();
487
488   // <cmd> --help
489   if ('help' == args[0]) {
490     args[0] = args[1];
491     args[1] = '--help';
492   }
493
494   // executable
495   var f = argv[1];
496   // name of the subcommand, link `pm-install`
497   var bin = basename(f, '.js') + '-' + args[0];
498
499
500   // In case of globally installed, get the base dir where executable
501   //  subcommand file should be located at
502   var baseDir
503     , link = readlink(f);
504
505   // when symbolink is relative path
506   if (link !== f && link.charAt(0) !== '/') {
507     link = path.join(dirname(f), link)
508   }
509   baseDir = dirname(link);
510
511   // prefer local `./<bin>` to bin in the $PATH
512   var localBin = path.join(baseDir, bin);
513
514   // whether bin file is a js script with explicit `.js` extension
515   var isExplicitJS = false;
516   if (exists(localBin + '.js')) {
517     bin = localBin + '.js';
518     isExplicitJS = true;
519   } else if (exists(localBin)) {
520     bin = localBin;
521   }
522
523   args = args.slice(1);
524
525   var proc;
526   if (process.platform !== 'win32') {
527     if (isExplicitJS) {
528       args.unshift(localBin);
529       // add executable arguments to spawn
530       args = (process.execArgv || []).concat(args);
531
532       proc = spawn('node', args, { stdio: 'inherit', customFds: [0, 1, 2] });
533     } else {
534       proc = spawn(bin, args, { stdio: 'inherit', customFds: [0, 1, 2] });
535     }
536   } else {
537     args.unshift(localBin);
538     proc = spawn(process.execPath, args, { stdio: 'inherit'});
539   }
540
541   proc.on('close', process.exit.bind(process));
542   proc.on('error', function(err) {
543     if (err.code == "ENOENT") {
544       console.error('\n  %s(1) does not exist, try --help\n', bin);
545     } else if (err.code == "EACCES") {
546       console.error('\n  %s(1) not executable. try chmod or run with root\n', bin);
547     }
548     process.exit(1);
549   });
550
551   // Store the reference to the child process
552   this.runningCommand = proc;
553 };
554
555 /**
556  * Normalize `args`, splitting joined short flags. For example
557  * the arg "-abc" is equivalent to "-a -b -c".
558  * This also normalizes equal sign and splits "--abc=def" into "--abc def".
559  *
560  * @param {Array} args
561  * @return {Array}
562  * @api private
563  */
564
565 Command.prototype.normalize = function(args) {
566   var ret = []
567     , arg
568     , lastOpt
569     , index;
570
571   for (var i = 0, len = args.length; i < len; ++i) {
572     arg = args[i];
573     if (i > 0) {
574       lastOpt = this.optionFor(args[i-1]);
575     }
576
577     if (arg === '--') {
578       // Honor option terminator
579       ret = ret.concat(args.slice(i));
580       break;
581     } else if (lastOpt && lastOpt.required) {
582       ret.push(arg);
583     } else if (arg.length > 1 && '-' == arg[0] && '-' != arg[1]) {
584       arg.slice(1).split('').forEach(function(c) {
585         ret.push('-' + c);
586       });
587     } else if (/^--/.test(arg) && ~(index = arg.indexOf('='))) {
588       ret.push(arg.slice(0, index), arg.slice(index + 1));
589     } else {
590       ret.push(arg);
591     }
592   }
593
594   return ret;
595 };
596
597 /**
598  * Parse command `args`.
599  *
600  * When listener(s) are available those
601  * callbacks are invoked, otherwise the "*"
602  * event is emitted and those actions are invoked.
603  *
604  * @param {Array} args
605  * @return {Command} for chaining
606  * @api private
607  */
608
609 Command.prototype.parseArgs = function(args, unknown) {
610   var name;
611
612   if (args.length) {
613     name = args[0];
614     if (this.listeners(name).length) {
615       this.emit(args.shift(), args, unknown);
616     } else {
617       this.emit('*', args);
618     }
619   } else {
620     outputHelpIfNecessary(this, unknown);
621
622     // If there were no args and we have unknown options,
623     // then they are extraneous and we need to error.
624     if (unknown.length > 0) {
625       this.unknownOption(unknown[0]);
626     }
627   }
628
629   return this;
630 };
631
632 /**
633  * Return an option matching `arg` if any.
634  *
635  * @param {String} arg
636  * @return {Option}
637  * @api private
638  */
639
640 Command.prototype.optionFor = function(arg) {
641   for (var i = 0, len = this.options.length; i < len; ++i) {
642     if (this.options[i].is(arg)) {
643       return this.options[i];
644     }
645   }
646 };
647
648 /**
649  * Parse options from `argv` returning `argv`
650  * void of these options.
651  *
652  * @param {Array} argv
653  * @return {Array}
654  * @api public
655  */
656
657 Command.prototype.parseOptions = function(argv) {
658   var args = []
659     , len = argv.length
660     , literal
661     , option
662     , arg;
663
664   var unknownOptions = [];
665
666   // parse options
667   for (var i = 0; i < len; ++i) {
668     arg = argv[i];
669
670     // literal args after --
671     if ('--' == arg) {
672       literal = true;
673       continue;
674     }
675
676     if (literal) {
677       args.push(arg);
678       continue;
679     }
680
681     // find matching Option
682     option = this.optionFor(arg);
683
684     // option is defined
685     if (option) {
686       // requires arg
687       if (option.required) {
688         arg = argv[++i];
689         if (null == arg) return this.optionMissingArgument(option);
690         this.emit(option.name(), arg);
691       // optional arg
692       } else if (option.optional) {
693         arg = argv[i+1];
694         if (null == arg || ('-' == arg[0] && '-' != arg)) {
695           arg = null;
696         } else {
697           ++i;
698         }
699         this.emit(option.name(), arg);
700       // bool
701       } else {
702         this.emit(option.name());
703       }
704       continue;
705     }
706
707     // looks like an option
708     if (arg.length > 1 && '-' == arg[0]) {
709       unknownOptions.push(arg);
710
711       // If the next argument looks like it might be
712       // an argument for this option, we pass it on.
713       // If it isn't, then it'll simply be ignored
714       if (argv[i+1] && '-' != argv[i+1][0]) {
715         unknownOptions.push(argv[++i]);
716       }
717       continue;
718     }
719
720     // arg
721     args.push(arg);
722   }
723
724   return { args: args, unknown: unknownOptions };
725 };
726
727 /**
728  * Return an object containing options as key-value pairs
729  *
730  * @return {Object}
731  * @api public
732  */
733 Command.prototype.opts = function() {
734   var result = {}
735     , len = this.options.length;
736
737   for (var i = 0 ; i < len; i++) {
738     var key = camelcase(this.options[i].name());
739     result[key] = key === 'version' ? this._version : this[key];
740   }
741   return result;
742 };
743
744 /**
745  * Argument `name` is missing.
746  *
747  * @param {String} name
748  * @api private
749  */
750
751 Command.prototype.missingArgument = function(name) {
752   console.error();
753   console.error("  error: missing required argument `%s'", name);
754   console.error();
755   process.exit(1);
756 };
757
758 /**
759  * `Option` is missing an argument, but received `flag` or nothing.
760  *
761  * @param {String} option
762  * @param {String} flag
763  * @api private
764  */
765
766 Command.prototype.optionMissingArgument = function(option, flag) {
767   console.error();
768   if (flag) {
769     console.error("  error: option `%s' argument missing, got `%s'", option.flags, flag);
770   } else {
771     console.error("  error: option `%s' argument missing", option.flags);
772   }
773   console.error();
774   process.exit(1);
775 };
776
777 /**
778  * Unknown option `flag`.
779  *
780  * @param {String} flag
781  * @api private
782  */
783
784 Command.prototype.unknownOption = function(flag) {
785   if (this._allowUnknownOption) return;
786   console.error();
787   console.error("  error: unknown option `%s'", flag);
788   console.error();
789   process.exit(1);
790 };
791
792 /**
793  * Variadic argument with `name` is not the last argument as required.
794  *
795  * @param {String} name
796  * @api private
797  */
798
799 Command.prototype.variadicArgNotLast = function(name) {
800   console.error();
801   console.error("  error: variadic arguments must be last `%s'", name);
802   console.error();
803   process.exit(1);
804 };
805
806 /**
807  * Set the program version to `str`.
808  *
809  * This method auto-registers the "-V, --version" flag
810  * which will print the version number when passed.
811  *
812  * @param {String} str
813  * @param {String} flags
814  * @return {Command} for chaining
815  * @api public
816  */
817
818 Command.prototype.version = function(str, flags) {
819   if (0 == arguments.length) return this._version;
820   this._version = str;
821   flags = flags || '-V, --version';
822   this.option(flags, 'output the version number');
823   this.on('version', function() {
824     process.stdout.write(str + '\n');
825     process.exit(0);
826   });
827   return this;
828 };
829
830 /**
831  * Set the description to `str`.
832  *
833  * @param {String} str
834  * @return {String|Command}
835  * @api public
836  */
837
838 Command.prototype.description = function(str) {
839   if (0 === arguments.length) return this._description;
840   this._description = str;
841   return this;
842 };
843
844 /**
845  * Set an alias for the command
846  *
847  * @param {String} alias
848  * @return {String|Command}
849  * @api public
850  */
851
852 Command.prototype.alias = function(alias) {
853   if (0 == arguments.length) return this._alias;
854   this._alias = alias;
855   return this;
856 };
857
858 /**
859  * Set / get the command usage `str`.
860  *
861  * @param {String} str
862  * @return {String|Command}
863  * @api public
864  */
865
866 Command.prototype.usage = function(str) {
867   var args = this._args.map(function(arg) {
868     return humanReadableArgName(arg);
869   });
870
871   var usage = '[options]'
872     + (this.commands.length ? ' [command]' : '')
873     + (this._args.length ? ' ' + args.join(' ') : '');
874
875   if (0 == arguments.length) return this._usage || usage;
876   this._usage = str;
877
878   return this;
879 };
880
881 /**
882  * Get the name of the command
883  *
884  * @param {String} name
885  * @return {String|Command}
886  * @api public
887  */
888
889 Command.prototype.name = function() {
890   return this._name;
891 };
892
893 /**
894  * Return the largest option length.
895  *
896  * @return {Number}
897  * @api private
898  */
899
900 Command.prototype.largestOptionLength = function() {
901   return this.options.reduce(function(max, option) {
902     return Math.max(max, option.flags.length);
903   }, 0);
904 };
905
906 /**
907  * Return help for options.
908  *
909  * @return {String}
910  * @api private
911  */
912
913 Command.prototype.optionHelp = function() {
914   var width = this.largestOptionLength();
915
916   // Prepend the help information
917   return [pad('-h, --help', width) + '  ' + 'output usage information']
918       .concat(this.options.map(function(option) {
919         return pad(option.flags, width) + '  ' + option.description;
920       }))
921       .join('\n');
922 };
923
924 /**
925  * Return command help documentation.
926  *
927  * @return {String}
928  * @api private
929  */
930
931 Command.prototype.commandHelp = function() {
932   if (!this.commands.length) return '';
933
934   var commands = this.commands.filter(function(cmd) {
935     return !cmd._noHelp;
936   }).map(function(cmd) {
937     var args = cmd._args.map(function(arg) {
938       return humanReadableArgName(arg);
939     }).join(' ');
940
941     return [
942       cmd._name
943         + (cmd._alias ? '|' + cmd._alias : '')
944         + (cmd.options.length ? ' [options]' : '')
945         + ' ' + args
946       , cmd.description()
947     ];
948   });
949
950   var width = commands.reduce(function(max, command) {
951     return Math.max(max, command[0].length);
952   }, 0);
953
954   return [
955     ''
956     , '  Commands:'
957     , ''
958     , commands.map(function(cmd) {
959       var desc = cmd[1] ? '  ' + cmd[1] : '';
960       return pad(cmd[0], width) + desc;
961     }).join('\n').replace(/^/gm, '    ')
962     , ''
963   ].join('\n');
964 };
965
966 /**
967  * Return program help documentation.
968  *
969  * @return {String}
970  * @api private
971  */
972
973 Command.prototype.helpInformation = function() {
974   var desc = [];
975   if (this._description) {
976     desc = [
977       '  ' + this._description
978       , ''
979     ];
980   }
981
982   var cmdName = this._name;
983   if (this._alias) {
984     cmdName = cmdName + '|' + this._alias;
985   }
986   var usage = [
987     ''
988     ,'  Usage: ' + cmdName + ' ' + this.usage()
989     , ''
990   ];
991
992   var cmds = [];
993   var commandHelp = this.commandHelp();
994   if (commandHelp) cmds = [commandHelp];
995
996   var options = [
997     '  Options:'
998     , ''
999     , '' + this.optionHelp().replace(/^/gm, '    ')
1000     , ''
1001     , ''
1002   ];
1003
1004   return usage
1005     .concat(cmds)
1006     .concat(desc)
1007     .concat(options)
1008     .join('\n');
1009 };
1010
1011 /**
1012  * Output help information for this command
1013  *
1014  * @api public
1015  */
1016
1017 Command.prototype.outputHelp = function(cb) {
1018   if (!cb) {
1019     cb = function(passthru) {
1020       return passthru;
1021     }
1022   }
1023   process.stdout.write(cb(this.helpInformation()));
1024   this.emit('--help');
1025 };
1026
1027 /**
1028  * Output help information and exit.
1029  *
1030  * @api public
1031  */
1032
1033 Command.prototype.help = function(cb) {
1034   this.outputHelp(cb);
1035   process.exit();
1036 };
1037
1038 /**
1039  * Camel-case the given `flag`
1040  *
1041  * @param {String} flag
1042  * @return {String}
1043  * @api private
1044  */
1045
1046 function camelcase(flag) {
1047   return flag.split('-').reduce(function(str, word) {
1048     return str + word[0].toUpperCase() + word.slice(1);
1049   });
1050 }
1051
1052 /**
1053  * Pad `str` to `width`.
1054  *
1055  * @param {String} str
1056  * @param {Number} width
1057  * @return {String}
1058  * @api private
1059  */
1060
1061 function pad(str, width) {
1062   var len = Math.max(0, width - str.length);
1063   return str + Array(len + 1).join(' ');
1064 }
1065
1066 /**
1067  * Output help information if necessary
1068  *
1069  * @param {Command} command to output help for
1070  * @param {Array} array of options to search for -h or --help
1071  * @api private
1072  */
1073
1074 function outputHelpIfNecessary(cmd, options) {
1075   options = options || [];
1076   for (var i = 0; i < options.length; i++) {
1077     if (options[i] == '--help' || options[i] == '-h') {
1078       cmd.outputHelp();
1079       process.exit(0);
1080     }
1081   }
1082 }
1083
1084 /**
1085  * Takes an argument an returns its human readable equivalent for help usage.
1086  *
1087  * @param {Object} arg
1088  * @return {String}
1089  * @api private
1090  */
1091
1092 function humanReadableArgName(arg) {
1093   var nameOutput = arg.name + (arg.variadic === true ? '...' : '');
1094
1095   return arg.required
1096     ? '<' + nameOutput + '>'
1097     : '[' + nameOutput + ']'
1098 }
1099
1100 // for versions before node v0.8 when there weren't `fs.existsSync`
1101 function exists(file) {
1102   try {
1103     if (fs.statSync(file).isFile()) {
1104       return true;
1105     }
1106   } catch (e) {
1107     return false;
1108   }
1109 }
1110