Brunobkr/llama.cpp_AlgMor24_github
ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.
03.1k
1/**2 * Module dependencies.3 */4 5var EventEmitter = require('events').EventEmitter;6var spawn = require('child_process').spawn;7var path = require('path');8var dirname = path.dirname;9var basename = path.basename;10var fs = require('fs');11 12/**13 * Inherit `Command` from `EventEmitter.prototype`.14 */15 16require('util').inherits(Command, EventEmitter);17 18/**19 * Expose the root command.20 */21 22exports = module.exports = new Command();23 24/**25 * Expose `Command`.26 */27 28exports.Command = Command;29 30/**31 * Expose `Option`.32 */33 34exports.Option = Option;35 36/**37 * Initialize a new `Option` with the given `flags` and `description`.38 *39 * @param {String} flags40 * @param {String} description41 * @api public42 */43 44function Option(flags, description) {45 this.flags = flags;46 this.required = flags.indexOf('<') >= 0;47 this.optional = flags.indexOf('[') >= 0;48 this.bool = flags.indexOf('-no-') === -1;49 flags = flags.split(/[ ,|]+/);50 if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift();51 this.long = flags.shift();52 this.description = description || '';53}54 55/**56 * Return option name.57 *58 * @return {String}59 * @api private60 */61 62Option.prototype.name = function() {63 return this.long64 .replace('--', '')65 .replace('no-', '');66};67 68/**69 * Return option name, in a camelcase format that can be used70 * as a object attribute key.71 *72 * @return {String}73 * @api private74 */75 76Option.prototype.attributeName = function() {77 return camelcase(this.name());78};79 80/**81 * Check if `arg` matches the short or long flag.82 *83 * @param {String} arg84 * @return {Boolean}85 * @api private86 */87 88Option.prototype.is = function(arg) {89 return this.short === arg || this.long === arg;90};91 92/**93 * Initialize a new `Command`.94 *95 * @param {String} name96 * @api public97 */98 99function Command(name) {100 this.commands = [];101 this.options = [];102 this._execs = {};103 this._allowUnknownOption = false;104 this._args = [];105 this._name = name || '';106}107 108/**109 * Add command `name`.110 *111 * The `.action()` callback is invoked when the112 * command `name` is specified via __ARGV__,113 * and the remaining arguments are applied to the114 * function for access.115 *116 * When the `name` is "*" an un-matched command117 * will be passed as the first arg, followed by118 * the rest of __ARGV__ remaining.119 *120 * Examples:121 *122 * program123 * .version('0.0.1')124 * .option('-C, --chdir <path>', 'change the working directory')125 * .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')126 * .option('-T, --no-tests', 'ignore test hook')127 *128 * program129 * .command('setup')130 * .description('run remote setup commands')131 * .action(function() {132 * console.log('setup');133 * });134 *135 * program136 * .command('exec <cmd>')137 * .description('run the given remote command')138 * .action(function(cmd) {139 * console.log('exec "%s"', cmd);140 * });141 *142 * program143 * .command('teardown <dir> [otherDirs...]')144 * .description('run teardown commands')145 * .action(function(dir, otherDirs) {146 * console.log('dir "%s"', dir);147 * if (otherDirs) {148 * otherDirs.forEach(function (oDir) {149 * console.log('dir "%s"', oDir);150 * });151 * }152 * });153 *154 * program155 * .command('*')156 * .description('deploy the given env')157 * .action(function(env) {158 * console.log('deploying "%s"', env);159 * });160 *161 * program.parse(process.argv);162 *163 * @param {String} name164 * @param {String} [desc] for git-style sub-commands165 * @return {Command} the new command166 * @api public167 */168 169Command.prototype.command = function(name, desc, opts) {170 if (typeof desc === 'object' && desc !== null) {171 opts = desc;172 desc = null;173 }174 opts = opts || {};175 var args = name.split(/ +/);176 var cmd = new Command(args.shift());177 178 if (desc) {179 cmd.description(desc);180 this.executables = true;181 this._execs[cmd._name] = true;182 if (opts.isDefault) this.defaultExecutable = cmd._name;183 }184 cmd._noHelp = !!opts.noHelp;185 this.commands.push(cmd);186 cmd.parseExpectedArgs(args);187 cmd.parent = this;188 189 if (desc) return this;190 return cmd;191};192 193/**194 * Define argument syntax for the top-level command.195 *196 * @api public197 */198 199Command.prototype.arguments = function(desc) {200 return this.parseExpectedArgs(desc.split(/ +/));201};202 203/**204 * Add an implicit `help [cmd]` subcommand205 * which invokes `--help` for the given command.206 *207 * @api private208 */209 210Command.prototype.addImplicitHelpCommand = function() {211 this.command('help [cmd]', 'display help for [cmd]');212};213 214/**215 * Parse expected `args`.216 *217 * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`.218 *219 * @param {Array} args220 * @return {Command} for chaining221 * @api public222 */223 224Command.prototype.parseExpectedArgs = function(args) {225 if (!args.length) return;226 var self = this;227 args.forEach(function(arg) {228 var argDetails = {229 required: false,230 name: '',231 variadic: false232 };233 234 switch (arg[0]) {235 case '<':236 argDetails.required = true;237 argDetails.name = arg.slice(1, -1);238 break;239 case '[':240 argDetails.name = arg.slice(1, -1);241 break;242 }243 244 if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') {245 argDetails.variadic = true;246 argDetails.name = argDetails.name.slice(0, -3);247 }248 if (argDetails.name) {249 self._args.push(argDetails);250 }251 });252 return this;253};254 255/**256 * Register callback `fn` for the command.257 *258 * Examples:259 *260 * program261 * .command('help')262 * .description('display verbose help')263 * .action(function() {264 * // output help here265 * });266 *267 * @param {Function} fn268 * @return {Command} for chaining269 * @api public270 */271 272Command.prototype.action = function(fn) {273 var self = this;274 var listener = function(args, unknown) {275 // Parse any so-far unknown options276 args = args || [];277 unknown = unknown || [];278 279 var parsed = self.parseOptions(unknown);280 281 // Output help if necessary282 outputHelpIfNecessary(self, parsed.unknown);283 284 // If there are still any unknown options, then we simply285 // die, unless someone asked for help, in which case we give it286 // to them, and then we die.287 if (parsed.unknown.length > 0) {288 self.unknownOption(parsed.unknown[0]);289 }290 291 // Leftover arguments need to be pushed back. Fixes issue #56292 if (parsed.args.length) args = parsed.args.concat(args);293 294 self._args.forEach(function(arg, i) {295 if (arg.required && args[i] == null) {296 self.missingArgument(arg.name);297 } else if (arg.variadic) {298 if (i !== self._args.length - 1) {299 self.variadicArgNotLast(arg.name);300 }301 302 args[i] = args.splice(i);303 }304 });305 306 // Always append ourselves to the end of the arguments,307 // to make sure we match the number of arguments the user308 // expects309 if (self._args.length) {310 args[self._args.length] = self;311 } else {312 args.push(self);313 }314 315 fn.apply(self, args);316 };317 var parent = this.parent || this;318 var name = parent === this ? '*' : this._name;319 parent.on('command:' + name, listener);320 if (this._alias) parent.on('command:' + this._alias, listener);321 return this;322};323 324/**325 * Define option with `flags`, `description` and optional326 * coercion `fn`.327 *328 * The `flags` string should contain both the short and long flags,329 * separated by comma, a pipe or space. The following are all valid330 * all will output this way when `--help` is used.331 *332 * "-p, --pepper"333 * "-p|--pepper"334 * "-p --pepper"335 *336 * Examples:337 *338 * // simple boolean defaulting to false339 * program.option('-p, --pepper', 'add pepper');340 *341 * --pepper342 * program.pepper343 * // => Boolean344 *345 * // simple boolean defaulting to true346 * program.option('-C, --no-cheese', 'remove cheese');347 *348 * program.cheese349 * // => true350 *351 * --no-cheese352 * program.cheese353 * // => false354 *355 * // required argument356 * program.option('-C, --chdir <path>', 'change the working directory');357 *358 * --chdir /tmp359 * program.chdir360 * // => "/tmp"361 *362 * // optional argument363 * program.option('-c, --cheese [type]', 'add cheese [marble]');364 *365 * @param {String} flags366 * @param {String} description367 * @param {Function|*} [fn] or default368 * @param {*} [defaultValue]369 * @return {Command} for chaining370 * @api public371 */372 373Command.prototype.option = function(flags, description, fn, defaultValue) {374 var self = this,375 option = new Option(flags, description),376 oname = option.name(),377 name = option.attributeName();378 379 // default as 3rd arg380 if (typeof fn !== 'function') {381 if (fn instanceof RegExp) {382 var regex = fn;383 fn = function(val, def) {384 var m = regex.exec(val);385 return m ? m[0] : def;386 };387 } else {388 defaultValue = fn;389 fn = null;390 }391 }392 393 // preassign default value only for --no-*, [optional], or <required>394 if (!option.bool || option.optional || option.required) {395 // when --no-* we make sure default is true396 if (!option.bool) defaultValue = true;397 // preassign only if we have a default398 if (defaultValue !== undefined) {399 self[name] = defaultValue;400 option.defaultValue = defaultValue;401 }402 }403 404 // register the option405 this.options.push(option);406 407 // when it's passed assign the value408 // and conditionally invoke the callback409 this.on('option:' + oname, function(val) {410 // coercion411 if (val !== null && fn) {412 val = fn(val, self[name] === undefined ? defaultValue : self[name]);413 }414 415 // unassigned or bool416 if (typeof self[name] === 'boolean' || typeof self[name] === 'undefined') {417 // if no value, bool true, and we have a default, then use it!418 if (val == null) {419 self[name] = option.bool420 ? defaultValue || true421 : false;422 } else {423 self[name] = val;424 }425 } else if (val !== null) {426 // reassign427 self[name] = val;428 }429 });430 431 return this;432};433 434/**435 * Allow unknown options on the command line.436 *437 * @param {Boolean} arg if `true` or omitted, no error will be thrown438 * for unknown options.439 * @api public440 */441Command.prototype.allowUnknownOption = function(arg) {442 this._allowUnknownOption = arguments.length === 0 || arg;443 return this;444};445 446/**447 * Parse `argv`, settings options and invoking commands when defined.448 *449 * @param {Array} argv450 * @return {Command} for chaining451 * @api public452 */453 454Command.prototype.parse = function(argv) {455 // implicit help456 if (this.executables) this.addImplicitHelpCommand();457 458 // store raw args459 this.rawArgs = argv;460 461 // guess name462 this._name = this._name || basename(argv[1], '.js');463 464 // github-style sub-commands with no sub-command465 if (this.executables && argv.length < 3 && !this.defaultExecutable) {466 // this user needs help467 argv.push('--help');468 }469 470 // process argv471 var parsed = this.parseOptions(this.normalize(argv.slice(2)));472 var args = this.args = parsed.args;473 474 var result = this.parseArgs(this.args, parsed.unknown);475 476 // executable sub-commands477 var name = result.args[0];478 479 var aliasCommand = null;480 // check alias of sub commands481 if (name) {482 aliasCommand = this.commands.filter(function(command) {483 return command.alias() === name;484 })[0];485 }486 487 if (this._execs[name] === true) {488 return this.executeSubCommand(argv, args, parsed.unknown);489 } else if (aliasCommand) {490 // is alias of a subCommand491 args[0] = aliasCommand._name;492 return this.executeSubCommand(argv, args, parsed.unknown);493 } else if (this.defaultExecutable) {494 // use the default subcommand495 args.unshift(this.defaultExecutable);496 return this.executeSubCommand(argv, args, parsed.unknown);497 }498 499 return result;500};501 502/**503 * Execute a sub-command executable.504 *505 * @param {Array} argv506 * @param {Array} args507 * @param {Array} unknown508 * @api private509 */510 511Command.prototype.executeSubCommand = function(argv, args, unknown) {512 args = args.concat(unknown);513 514 if (!args.length) this.help();515 if (args[0] === 'help' && args.length === 1) this.help();516 517 // <cmd> --help518 if (args[0] === 'help') {519 args[0] = args[1];520 args[1] = '--help';521 }522 523 // executable524 var f = argv[1];525 // name of the subcommand, link `pm-install`526 var bin = basename(f, path.extname(f)) + '-' + args[0];527 528 // In case of globally installed, get the base dir where executable529 // subcommand file should be located at530 var baseDir;531 532 var resolvedLink = fs.realpathSync(f);533 534 baseDir = dirname(resolvedLink);535 536 // prefer local `./<bin>` to bin in the $PATH537 var localBin = path.join(baseDir, bin);538 539 // whether bin file is a js script with explicit `.js` or `.ts` extension540 var isExplicitJS = false;541 if (exists(localBin + '.js')) {542 bin = localBin + '.js';543 isExplicitJS = true;544 } else if (exists(localBin + '.ts')) {545 bin = localBin + '.ts';546 isExplicitJS = true;547 } else if (exists(localBin)) {548 bin = localBin;549 }550 551 args = args.slice(1);552 553 var proc;554 if (process.platform !== 'win32') {555 if (isExplicitJS) {556 args.unshift(bin);557 // add executable arguments to spawn558 args = (process.execArgv || []).concat(args);559 560 proc = spawn(process.argv[0], args, { stdio: 'inherit', customFds: [0, 1, 2] });561 } else {562 proc = spawn(bin, args, { stdio: 'inherit', customFds: [0, 1, 2] });563 }564 } else {565 args.unshift(bin);566 proc = spawn(process.execPath, args, { stdio: 'inherit' });567 }568 569 var signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP'];570 signals.forEach(function(signal) {571 process.on(signal, function() {572 if (proc.killed === false && proc.exitCode === null) {573 proc.kill(signal);574 }575 });576 });577 proc.on('close', process.exit.bind(process));578 proc.on('error', function(err) {579 if (err.code === 'ENOENT') {580 console.error('error: %s(1) does not exist, try --help', bin);581 } else if (err.code === 'EACCES') {582 console.error('error: %s(1) not executable. try chmod or run with root', bin);583 }584 process.exit(1);585 });586 587 // Store the reference to the child process588 this.runningCommand = proc;589};590 591/**592 * Normalize `args`, splitting joined short flags. For example593 * the arg "-abc" is equivalent to "-a -b -c".594 * This also normalizes equal sign and splits "--abc=def" into "--abc def".595 *596 * @param {Array} args597 * @return {Array}598 * @api private599 */600 601Command.prototype.normalize = function(args) {602 var ret = [],603 arg,604 lastOpt,605 index;606 607 for (var i = 0, len = args.length; i < len; ++i) {608 arg = args[i];609 if (i > 0) {610 lastOpt = this.optionFor(args[i - 1]);611 }612 613 if (arg === '--') {614 // Honor option terminator615 ret = ret.concat(args.slice(i));616 break;617 } else if (lastOpt && lastOpt.required) {618 ret.push(arg);619 } else if (arg.length > 1 && arg[0] === '-' && arg[1] !== '-') {620 arg.slice(1).split('').forEach(function(c) {621 ret.push('-' + c);622 });623 } else if (/^--/.test(arg) && ~(index = arg.indexOf('='))) {624 ret.push(arg.slice(0, index), arg.slice(index + 1));625 } else {626 ret.push(arg);627 }628 }629 630 return ret;631};632 633/**634 * Parse command `args`.635 *636 * When listener(s) are available those637 * callbacks are invoked, otherwise the "*"638 * event is emitted and those actions are invoked.639 *640 * @param {Array} args641 * @return {Command} for chaining642 * @api private643 */644 645Command.prototype.parseArgs = function(args, unknown) {646 var name;647 648 if (args.length) {649 name = args[0];650 if (this.listeners('command:' + name).length) {651 this.emit('command:' + args.shift(), args, unknown);652 } else {653 this.emit('command:*', args);654 }655 } else {656 outputHelpIfNecessary(this, unknown);657 658 // If there were no args and we have unknown options,659 // then they are extraneous and we need to error.660 if (unknown.length > 0) {661 this.unknownOption(unknown[0]);662 }663 if (this.commands.length === 0 &&664 this._args.filter(function(a) { return a.required; }).length === 0) {665 this.emit('command:*');666 }667 }668 669 return this;670};671 672/**673 * Return an option matching `arg` if any.674 *675 * @param {String} arg676 * @return {Option}677 * @api private678 */679 680Command.prototype.optionFor = function(arg) {681 for (var i = 0, len = this.options.length; i < len; ++i) {682 if (this.options[i].is(arg)) {683 return this.options[i];684 }685 }686};687 688/**689 * Parse options from `argv` returning `argv`690 * void of these options.691 *692 * @param {Array} argv693 * @return {Array}694 * @api public695 */696 697Command.prototype.parseOptions = function(argv) {698 var args = [],699 len = argv.length,700 literal,701 option,702 arg;703 704 var unknownOptions = [];705 706 // parse options707 for (var i = 0; i < len; ++i) {708 arg = argv[i];709 710 // literal args after --711 if (literal) {712 args.push(arg);713 continue;714 }715 716 if (arg === '--') {717 literal = true;718 continue;719 }720 721 // find matching Option722 option = this.optionFor(arg);723 724 // option is defined725 if (option) {726 // requires arg727 if (option.required) {728 arg = argv[++i];729 if (arg == null) return this.optionMissingArgument(option);730 this.emit('option:' + option.name(), arg);731 // optional arg732 } else if (option.optional) {733 arg = argv[i + 1];734 if (arg == null || (arg[0] === '-' && arg !== '-')) {735 arg = null;736 } else {737 ++i;738 }739 this.emit('option:' + option.name(), arg);740 // bool741 } else {742 this.emit('option:' + option.name());743 }744 continue;745 }746 747 // looks like an option748 if (arg.length > 1 && arg[0] === '-') {749 unknownOptions.push(arg);750 751 // If the next argument looks like it might be752 // an argument for this option, we pass it on.753 // If it isn't, then it'll simply be ignored754 if ((i + 1) < argv.length && argv[i + 1][0] !== '-') {755 unknownOptions.push(argv[++i]);756 }757 continue;758 }759 760 // arg761 args.push(arg);762 }763 764 return { args: args, unknown: unknownOptions };765};766 767/**768 * Return an object containing options as key-value pairs769 *770 * @return {Object}771 * @api public772 */773Command.prototype.opts = function() {774 var result = {},775 len = this.options.length;776 777 for (var i = 0; i < len; i++) {778 var key = this.options[i].attributeName();779 result[key] = key === this._versionOptionName ? this._version : this[key];780 }781 return result;782};783 784/**785 * Argument `name` is missing.786 *787 * @param {String} name788 * @api private789 */790 791Command.prototype.missingArgument = function(name) {792 console.error("error: missing required argument `%s'", name);793 process.exit(1);794};795 796/**797 * `Option` is missing an argument, but received `flag` or nothing.798 *799 * @param {String} option800 * @param {String} flag801 * @api private802 */803 804Command.prototype.optionMissingArgument = function(option, flag) {805 if (flag) {806 console.error("error: option `%s' argument missing, got `%s'", option.flags, flag);807 } else {808 console.error("error: option `%s' argument missing", option.flags);809 }810 process.exit(1);811};812 813/**814 * Unknown option `flag`.815 *816 * @param {String} flag817 * @api private818 */819 820Command.prototype.unknownOption = function(flag) {821 if (this._allowUnknownOption) return;822 console.error("error: unknown option `%s'", flag);823 process.exit(1);824};825 826/**827 * Variadic argument with `name` is not the last argument as required.828 *829 * @param {String} name830 * @api private831 */832 833Command.prototype.variadicArgNotLast = function(name) {834 console.error("error: variadic arguments must be last `%s'", name);835 process.exit(1);836};837 838/**839 * Set the program version to `str`.840 *841 * This method auto-registers the "-V, --version" flag842 * which will print the version number when passed.843 *844 * @param {String} str845 * @param {String} [flags]846 * @return {Command} for chaining847 * @api public848 */849 850Command.prototype.version = function(str, flags) {851 if (arguments.length === 0) return this._version;852 this._version = str;853 flags = flags || '-V, --version';854 var versionOption = new Option(flags, 'output the version number');855 this._versionOptionName = versionOption.long.substr(2) || 'version';856 this.options.push(versionOption);857 this.on('option:' + this._versionOptionName, function() {858 process.stdout.write(str + '\n');859 process.exit(0);860 });861 return this;862};863 864/**865 * Set the description to `str`.866 *867 * @param {String} str868 * @param {Object} argsDescription869 * @return {String|Command}870 * @api public871 */872 873Command.prototype.description = function(str, argsDescription) {874 if (arguments.length === 0) return this._description;875 this._description = str;876 this._argsDescription = argsDescription;877 return this;878};879 880/**881 * Set an alias for the command882 *883 * @param {String} alias884 * @return {String|Command}885 * @api public886 */887 888Command.prototype.alias = function(alias) {889 var command = this;890 if (this.commands.length !== 0) {891 command = this.commands[this.commands.length - 1];892 }893 894 if (arguments.length === 0) return command._alias;895 896 if (alias === command._name) throw new Error('Command alias can\'t be the same as its name');897 898 command._alias = alias;899 return this;900};901 902/**903 * Set / get the command usage `str`.904 *905 * @param {String} str906 * @return {String|Command}907 * @api public908 */909 910Command.prototype.usage = function(str) {911 var args = this._args.map(function(arg) {912 return humanReadableArgName(arg);913 });914 915 var usage = '[options]' +916 (this.commands.length ? ' [command]' : '') +917 (this._args.length ? ' ' + args.join(' ') : '');918 919 if (arguments.length === 0) return this._usage || usage;920 this._usage = str;921 922 return this;923};924 925/**926 * Get or set the name of the command927 *928 * @param {String} str929 * @return {String|Command}930 * @api public931 */932 933Command.prototype.name = function(str) {934 if (arguments.length === 0) return this._name;935 this._name = str;936 return this;937};938 939/**940 * Return prepared commands.941 *942 * @return {Array}943 * @api private944 */945 946Command.prototype.prepareCommands = function() {947 return this.commands.filter(function(cmd) {948 return !cmd._noHelp;949 }).map(function(cmd) {950 var args = cmd._args.map(function(arg) {951 return humanReadableArgName(arg);952 }).join(' ');953 954 return [955 cmd._name +956 (cmd._alias ? '|' + cmd._alias : '') +957 (cmd.options.length ? ' [options]' : '') +958 (args ? ' ' + args : ''),959 cmd._description960 ];961 });962};963 964/**965 * Return the largest command length.966 *967 * @return {Number}968 * @api private969 */970 971Command.prototype.largestCommandLength = function() {972 var commands = this.prepareCommands();973 return commands.reduce(function(max, command) {974 return Math.max(max, command[0].length);975 }, 0);976};977 978/**979 * Return the largest option length.980 *981 * @return {Number}982 * @api private983 */984 985Command.prototype.largestOptionLength = function() {986 var options = [].slice.call(this.options);987 options.push({988 flags: '-h, --help'989 });990 return options.reduce(function(max, option) {991 return Math.max(max, option.flags.length);992 }, 0);993};994 995/**996 * Return the largest arg length.997 *998 * @return {Number}999 * @api private1000 */1001 1002Command.prototype.largestArgLength = function() {1003 return this._args.reduce(function(max, arg) {1004 return Math.max(max, arg.name.length);1005 }, 0);1006};1007 1008/**1009 * Return the pad width.1010 *1011 * @return {Number}1012 * @api private1013 */1014 1015Command.prototype.padWidth = function() {1016 var width = this.largestOptionLength();1017 if (this._argsDescription && this._args.length) {1018 if (this.largestArgLength() > width) {1019 width = this.largestArgLength();1020 }1021 }1022 1023 if (this.commands && this.commands.length) {1024 if (this.largestCommandLength() > width) {1025 width = this.largestCommandLength();1026 }1027 }1028 1029 return width;1030};1031 1032/**1033 * Return help for options.1034 *1035 * @return {String}1036 * @api private1037 */1038 1039Command.prototype.optionHelp = function() {1040 var width = this.padWidth();1041 1042 // Append the help information1043 return this.options.map(function(option) {1044 return pad(option.flags, width) + ' ' + option.description +1045 ((option.bool && option.defaultValue !== undefined) ? ' (default: ' + JSON.stringify(option.defaultValue) + ')' : '');1046 }).concat([pad('-h, --help', width) + ' ' + 'output usage information'])1047 .join('\n');1048};1049 1050/**1051 * Return command help documentation.1052 *1053 * @return {String}1054 * @api private1055 */1056 1057Command.prototype.commandHelp = function() {1058 if (!this.commands.length) return '';1059 1060 var commands = this.prepareCommands();1061 var width = this.padWidth();1062 1063 return [1064 'Commands:',1065 commands.map(function(cmd) {1066 var desc = cmd[1] ? ' ' + cmd[1] : '';1067 return (desc ? pad(cmd[0], width) : cmd[0]) + desc;1068 }).join('\n').replace(/^/gm, ' '),1069 ''1070 ].join('\n');1071};1072 1073/**1074 * Return program help documentation.1075 *1076 * @return {String}1077 * @api private1078 */1079 1080Command.prototype.helpInformation = function() {1081 var desc = [];1082 if (this._description) {1083 desc = [1084 this._description,1085 ''1086 ];1087 1088 var argsDescription = this._argsDescription;1089 if (argsDescription && this._args.length) {1090 var width = this.padWidth();1091 desc.push('Arguments:');1092 desc.push('');1093 this._args.forEach(function(arg) {1094 desc.push(' ' + pad(arg.name, width) + ' ' + argsDescription[arg.name]);1095 });1096 desc.push('');1097 }1098 }1099 1100 var cmdName = this._name;1101 if (this._alias) {1102 cmdName = cmdName + '|' + this._alias;1103 }1104 var usage = [1105 'Usage: ' + cmdName + ' ' + this.usage(),1106 ''1107 ];1108 1109 var cmds = [];1110 var commandHelp = this.commandHelp();1111 if (commandHelp) cmds = [commandHelp];1112 1113 var options = [1114 'Options:',1115 '' + this.optionHelp().replace(/^/gm, ' '),1116 ''1117 ];1118 1119 return usage1120 .concat(desc)1121 .concat(options)1122 .concat(cmds)1123 .join('\n');1124};1125 1126/**1127 * Output help information for this command1128 *1129 * @api public1130 */1131 1132Command.prototype.outputHelp = function(cb) {1133 if (!cb) {1134 cb = function(passthru) {1135 return passthru;1136 };1137 }1138 process.stdout.write(cb(this.helpInformation()));1139 this.emit('--help');1140};1141 1142/**1143 * Output help information and exit.1144 *1145 * @api public1146 */1147 1148Command.prototype.help = function(cb) {1149 this.outputHelp(cb);1150 process.exit();1151};1152 1153/**1154 * Camel-case the given `flag`1155 *1156 * @param {String} flag1157 * @return {String}1158 * @api private1159 */1160 1161function camelcase(flag) {1162 return flag.split('-').reduce(function(str, word) {1163 return str + word[0].toUpperCase() + word.slice(1);1164 });1165}1166 1167/**1168 * Pad `str` to `width`.1169 *1170 * @param {String} str1171 * @param {Number} width1172 * @return {String}1173 * @api private1174 */1175 1176function pad(str, width) {1177 var len = Math.max(0, width - str.length);1178 return str + Array(len + 1).join(' ');1179}1180 1181/**1182 * Output help information if necessary1183 *1184 * @param {Command} command to output help for1185 * @param {Array} array of options to search for -h or --help1186 * @api private1187 */1188 1189function outputHelpIfNecessary(cmd, options) {1190 options = options || [];1191 for (var i = 0; i < options.length; i++) {1192 if (options[i] === '--help' || options[i] === '-h') {1193 cmd.outputHelp();1194 process.exit(0);1195 }1196 }1197}1198 1199/**1200 * Takes an argument an returns its human readable equivalent for help usage.