CoolFace
Apppublic

Umama-at-Bluchip/Quick-UI

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
index.js1650 linesDownload Raw Back to commander
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; // A value must be supplied when the option is specified.47  this.optional = flags.indexOf('[') >= 0; // A value is optional when the option is specified.48  this.mandatory = false; // The option must have a value after parsing, which usually means it must be specified on command line.49  this.negate = flags.indexOf('-no-') !== -1;50  flags = flags.split(/[ ,|]+/);51  if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift();52  this.long = flags.shift();53  this.description = description || '';54}55 56/**57 * Return option name.58 *59 * @return {String}60 * @api private61 */62 63Option.prototype.name = function() {64  return this.long.replace(/^--/, '');65};66 67/**68 * Return option name, in a camelcase format that can be used69 * as a object attribute key.70 *71 * @return {String}72 * @api private73 */74 75Option.prototype.attributeName = function() {76  return camelcase(this.name().replace(/^no-/, ''));77};78 79/**80 * Check if `arg` matches the short or long flag.81 *82 * @param {String} arg83 * @return {Boolean}84 * @api private85 */86 87Option.prototype.is = function(arg) {88  return this.short === arg || this.long === arg;89};90 91/**92 * CommanderError class93 * @class94 */95class CommanderError extends Error {96  /**97   * Constructs the CommanderError class98   * @param {Number} exitCode suggested exit code which could be used with process.exit99   * @param {String} code an id string representing the error100   * @param {String} message human-readable description of the error101   * @constructor102   */103  constructor(exitCode, code, message) {104    super(message);105    // properly capture stack trace in Node.js106    Error.captureStackTrace(this, this.constructor);107    this.name = this.constructor.name;108    this.code = code;109    this.exitCode = exitCode;110  }111}112 113exports.CommanderError = CommanderError;114 115/**116 * Initialize a new `Command`.117 *118 * @param {String} [name]119 * @api public120 */121 122function Command(name) {123  this.commands = [];124  this.options = [];125  this._execs = new Set();126  this._allowUnknownOption = false;127  this._args = [];128  this._name = name || '';129  this._optionValues = {};130  this._storeOptionsAsProperties = true; // backwards compatible by default131  this._passCommandToAction = true; // backwards compatible by default132  this._actionResults = [];133 134  this._helpFlags = '-h, --help';135  this._helpDescription = 'output usage information';136  this._helpShortFlag = '-h';137  this._helpLongFlag = '--help';138}139 140/**141 * Define a command.142 *143 * There are two styles of command: pay attention to where to put the description.144 *145 * Examples:146 *147 *      // Command implemented using action handler (description is supplied separately to `.command`)148 *      program149 *        .command('clone <source> [destination]')150 *        .description('clone a repository into a newly created directory')151 *        .action((source, destination) => {152 *          console.log('clone command called');153 *        });154 *155 *      // Command implemented using separate executable file (description is second parameter to `.command`)156 *      program157 *        .command('start <service>', 'start named service')158 *        .command('stop [service]', 'stop named service, or all if no name supplied');159 *160 * @param {string} nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`161 * @param {Object|string} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)162 * @param {Object} [execOpts] - configuration options (for executable)163 * @return {Command} returns new command for action handler, or top-level command for executable command164 * @api public165 */166 167Command.prototype.command = function(nameAndArgs, actionOptsOrExecDesc, execOpts) {168  var desc = actionOptsOrExecDesc;169  var opts = execOpts;170  if (typeof desc === 'object' && desc !== null) {171    opts = desc;172    desc = null;173  }174  opts = opts || {};175  var args = nameAndArgs.split(/ +/);176  var cmd = new Command(args.shift());177 178  if (desc) {179    cmd.description(desc);180    this.executables = true;181    this._execs.add(cmd._name);182    if (opts.isDefault) this.defaultExecutable = cmd._name;183  }184  cmd._noHelp = !!opts.noHelp;185  cmd._helpFlags = this._helpFlags;186  cmd._helpDescription = this._helpDescription;187  cmd._helpShortFlag = this._helpShortFlag;188  cmd._helpLongFlag = this._helpLongFlag;189  cmd._exitCallback = this._exitCallback;190  cmd._storeOptionsAsProperties = this._storeOptionsAsProperties;191  cmd._passCommandToAction = this._passCommandToAction;192 193  cmd._executableFile = opts.executableFile; // Custom name for executable file194  this.commands.push(cmd);195  cmd.parseExpectedArgs(args);196  cmd.parent = this;197 198  if (desc) return this;199  return cmd;200};201 202/**203 * Define argument syntax for the top-level command.204 *205 * @api public206 */207 208Command.prototype.arguments = function(desc) {209  return this.parseExpectedArgs(desc.split(/ +/));210};211 212/**213 * Add an implicit `help [cmd]` subcommand214 * which invokes `--help` for the given command.215 *216 * @api private217 */218 219Command.prototype.addImplicitHelpCommand = function() {220  this.command('help [cmd]', 'display help for [cmd]');221};222 223/**224 * Parse expected `args`.225 *226 * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`.227 *228 * @param {Array} args229 * @return {Command} for chaining230 * @api public231 */232 233Command.prototype.parseExpectedArgs = function(args) {234  if (!args.length) return;235  var self = this;236  args.forEach(function(arg) {237    var argDetails = {238      required: false,239      name: '',240      variadic: false241    };242 243    switch (arg[0]) {244      case '<':245        argDetails.required = true;246        argDetails.name = arg.slice(1, -1);247        break;248      case '[':249        argDetails.name = arg.slice(1, -1);250        break;251    }252 253    if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') {254      argDetails.variadic = true;255      argDetails.name = argDetails.name.slice(0, -3);256    }257    if (argDetails.name) {258      self._args.push(argDetails);259    }260  });261  return this;262};263 264/**265 * Register callback to use as replacement for calling process.exit.266 *267 * @param {Function} [fn] optional callback which will be passed a CommanderError, defaults to throwing268 * @return {Command} for chaining269 * @api public270 */271 272Command.prototype.exitOverride = function(fn) {273  if (fn) {274    this._exitCallback = fn;275  } else {276    this._exitCallback = function(err) {277      if (err.code !== 'commander.executeSubCommandAsync') {278        throw err;279      } else {280        // Async callback from spawn events, not useful to throw.281      }282    };283  }284  return this;285};286 287/**288 * Call process.exit, and _exitCallback if defined.289 *290 * @param {Number} exitCode exit code for using with process.exit291 * @param {String} code an id string representing the error292 * @param {String} message human-readable description of the error293 * @return never294 * @api private295 */296 297Command.prototype._exit = function(exitCode, code, message) {298  if (this._exitCallback) {299    this._exitCallback(new CommanderError(exitCode, code, message));300    // Expecting this line is not reached.301  }302  process.exit(exitCode);303};304 305/**306 * Register callback `fn` for the command.307 *308 * Examples:309 *310 *      program311 *        .command('help')312 *        .description('display verbose help')313 *        .action(function() {314 *           // output help here315 *        });316 *317 * @param {Function} fn318 * @return {Command} for chaining319 * @api public320 */321 322Command.prototype.action = function(fn) {323  var self = this;324  var listener = function(args, unknown) {325    // Parse any so-far unknown options326    args = args || [];327    unknown = unknown || [];328 329    var parsed = self.parseOptions(unknown);330 331    // Output help if necessary332    outputHelpIfRequested(self, parsed.unknown);333    self._checkForMissingMandatoryOptions();334 335    // If there are still any unknown options, then we simply336    // die, unless someone asked for help, in which case we give it337    // to them, and then we die.338    if (parsed.unknown.length > 0) {339      self.unknownOption(parsed.unknown[0]);340    }341 342    // Leftover arguments need to be pushed back. Fixes issue #56343    if (parsed.args.length) args = parsed.args.concat(args);344 345    self._args.forEach(function(arg, i) {346      if (arg.required && args[i] == null) {347        self.missingArgument(arg.name);348      } else if (arg.variadic) {349        if (i !== self._args.length - 1) {350          self.variadicArgNotLast(arg.name);351        }352 353        args[i] = args.splice(i);354      }355    });356 357    // The .action callback takes an extra parameter which is the command itself.358    var expectedArgsCount = self._args.length;359    var actionArgs = args.slice(0, expectedArgsCount);360    if (self._passCommandToAction) {361      actionArgs[expectedArgsCount] = self;362    } else {363      actionArgs[expectedArgsCount] = self.opts();364    }365    // Add the extra arguments so available too.366    if (args.length > expectedArgsCount) {367      actionArgs.push(args.slice(expectedArgsCount));368    }369 370    const actionResult = fn.apply(self, actionArgs);371    // Remember result in case it is async. Assume parseAsync getting called on root.372    let rootCommand = self;373    while (rootCommand.parent) {374      rootCommand = rootCommand.parent;375    }376    rootCommand._actionResults.push(actionResult);377  };378  var parent = this.parent || this;379  var name = parent === this ? '*' : this._name;380  parent.on('command:' + name, listener);381  if (this._alias) parent.on('command:' + this._alias, listener);382  return this;383};384 385/**386 * Internal implementation shared by .option() and .requiredOption()387 *388 * @param {Object} config389 * @param {String} flags390 * @param {String} description391 * @param {Function|*} [fn] - custom option processing function or default vaue392 * @param {*} [defaultValue]393 * @return {Command} for chaining394 * @api private395 */396 397Command.prototype._optionEx = function(config, flags, description, fn, defaultValue) {398  var self = this,399    option = new Option(flags, description),400    oname = option.name(),401    name = option.attributeName();402  option.mandatory = !!config.mandatory;403 404  // default as 3rd arg405  if (typeof fn !== 'function') {406    if (fn instanceof RegExp) {407      // This is a bit simplistic (especially no error messages), and probably better handled by caller using custom option processing.408      // No longer documented in README, but still present for backwards compatibility.409      var regex = fn;410      fn = function(val, def) {411        var m = regex.exec(val);412        return m ? m[0] : def;413      };414    } else {415      defaultValue = fn;416      fn = null;417    }418  }419 420  // preassign default value for --no-*, [optional], <required>, or plain flag if boolean value421  if (option.negate || option.optional || option.required || typeof defaultValue === 'boolean') {422    // when --no-foo we make sure default is true, unless a --foo option is already defined423    if (option.negate) {424      const positiveLongFlag = option.long.replace(/^--no-/, '--');425      defaultValue = self.optionFor(positiveLongFlag) ? self._getOptionValue(name) : true;426    }427    // preassign only if we have a default428    if (defaultValue !== undefined) {429      self._setOptionValue(name, defaultValue);430      option.defaultValue = defaultValue;431    }432  }433 434  // register the option435  this.options.push(option);436 437  // when it's passed assign the value438  // and conditionally invoke the callback439  this.on('option:' + oname, function(val) {440    // coercion441    if (val !== null && fn) {442      val = fn(val, self._getOptionValue(name) === undefined ? defaultValue : self._getOptionValue(name));443    }444 445    // unassigned or boolean value446    if (typeof self._getOptionValue(name) === 'boolean' || typeof self._getOptionValue(name) === 'undefined') {447      // if no value, negate false, and we have a default, then use it!448      if (val == null) {449        self._setOptionValue(name, option.negate450          ? false451          : defaultValue || true);452      } else {453        self._setOptionValue(name, val);454      }455    } else if (val !== null) {456      // reassign457      self._setOptionValue(name, option.negate ? false : val);458    }459  });460 461  return this;462};463 464/**465 * Define option with `flags`, `description` and optional466 * coercion `fn`.467 *468 * The `flags` string should contain both the short and long flags,469 * separated by comma, a pipe or space. The following are all valid470 * all will output this way when `--help` is used.471 *472 *    "-p, --pepper"473 *    "-p|--pepper"474 *    "-p --pepper"475 *476 * Examples:477 *478 *     // simple boolean defaulting to undefined479 *     program.option('-p, --pepper', 'add pepper');480 *481 *     program.pepper482 *     // => undefined483 *484 *     --pepper485 *     program.pepper486 *     // => true487 *488 *     // simple boolean defaulting to true (unless non-negated option is also defined)489 *     program.option('-C, --no-cheese', 'remove cheese');490 *491 *     program.cheese492 *     // => true493 *494 *     --no-cheese495 *     program.cheese496 *     // => false497 *498 *     // required argument499 *     program.option('-C, --chdir <path>', 'change the working directory');500 *501 *     --chdir /tmp502 *     program.chdir503 *     // => "/tmp"504 *505 *     // optional argument506 *     program.option('-c, --cheese [type]', 'add cheese [marble]');507 *508 * @param {String} flags509 * @param {String} description510 * @param {Function|*} [fn] - custom option processing function or default vaue511 * @param {*} [defaultValue]512 * @return {Command} for chaining513 * @api public514 */515 516Command.prototype.option = function(flags, description, fn, defaultValue) {517  return this._optionEx({}, flags, description, fn, defaultValue);518};519 520/*521 * Add a required option which must have a value after parsing. This usually means522 * the option must be specified on the command line. (Otherwise the same as .option().)523 *524 * The `flags` string should contain both the short and long flags, separated by comma, a pipe or space.525 *526 * @param {String} flags527 * @param {String} description528 * @param {Function|*} [fn] - custom option processing function or default vaue529 * @param {*} [defaultValue]530 * @return {Command} for chaining531 * @api public532 */533 534Command.prototype.requiredOption = function(flags, description, fn, defaultValue) {535  return this._optionEx({ mandatory: true }, flags, description, fn, defaultValue);536};537 538/**539 * Allow unknown options on the command line.540 *541 * @param {Boolean} arg if `true` or omitted, no error will be thrown542 * for unknown options.543 * @api public544 */545Command.prototype.allowUnknownOption = function(arg) {546  this._allowUnknownOption = arguments.length === 0 || arg;547  return this;548};549 550/**551  * Whether to store option values as properties on command object,552  * or store separately (specify false). In both cases the option values can be accessed using .opts().553  *554  * @param {boolean} value555  * @return {Command} Command for chaining556  * @api public557  */558 559Command.prototype.storeOptionsAsProperties = function(value) {560  this._storeOptionsAsProperties = (value === undefined) || value;561  if (this.options.length) {562    // This is for programmer, not end user.563    console.error('Commander usage error: call storeOptionsAsProperties before adding options');564  }565  return this;566};567 568/**569  * Whether to pass command to action handler,570  * or just the options (specify false).571  *572  * @param {boolean} value573  * @return {Command} Command for chaining574  * @api public575  */576 577Command.prototype.passCommandToAction = function(value) {578  this._passCommandToAction = (value === undefined) || value;579  return this;580};581 582/**583 * Store option value584 *585 * @param {String} key586 * @param {Object} value587 * @api private588 */589 590Command.prototype._setOptionValue = function(key, value) {591  if (this._storeOptionsAsProperties) {592    this[key] = value;593  } else {594    this._optionValues[key] = value;595  }596};597 598/**599 * Retrieve option value600 *601 * @param {String} key602 * @return {Object} value603 * @api private604 */605 606Command.prototype._getOptionValue = function(key) {607  if (this._storeOptionsAsProperties) {608    return this[key];609  }610  return this._optionValues[key];611};612 613/**614 * Parse `argv`, setting options and invoking commands when defined.615 *616 * @param {Array} argv617 * @return {Command} for chaining618 * @api public619 */620 621Command.prototype.parse = function(argv) {622  // implicit help623  if (this.executables) this.addImplicitHelpCommand();624 625  // store raw args626  this.rawArgs = argv;627 628  // guess name629  this._name = this._name || basename(argv[1], '.js');630 631  // github-style sub-commands with no sub-command632  if (this.executables && argv.length < 3 && !this.defaultExecutable) {633    // this user needs help634    argv.push(this._helpLongFlag);635  }636 637  // process argv638  var normalized = this.normalize(argv.slice(2));639  var parsed = this.parseOptions(normalized);640  var args = this.args = parsed.args;641 642  var result = this.parseArgs(this.args, parsed.unknown);643 644  if (args[0] === 'help' && args.length === 1) this.help();645 646  // Note for future: we could return early if we found an action handler in parseArgs, as none of following code needed?647 648  // <cmd> --help649  if (args[0] === 'help') {650    args[0] = args[1];651    args[1] = this._helpLongFlag;652  } else {653    // If calling through to executable subcommand we could check for help flags before failing,654    // but a somewhat unlikely case since program options not passed to executable subcommands.655    // Wait for reports to see if check needed and what usage pattern is.656    this._checkForMissingMandatoryOptions();657  }658 659  // executable sub-commands660  // (Debugging note for future: args[0] is not right if an action has been called)661  var name = result.args[0];662  var subCommand = null;663 664  // Look for subcommand665  if (name) {666    subCommand = this.commands.find(function(command) {667      return command._name === name;668    });669  }670 671  // Look for alias672  if (!subCommand && name) {673    subCommand = this.commands.find(function(command) {674      return command.alias() === name;675    });676    if (subCommand) {677      name = subCommand._name;678      args[0] = name;679    }680  }681 682  // Look for default subcommand683  if (!subCommand && this.defaultExecutable) {684    name = this.defaultExecutable;685    args.unshift(name);686    subCommand = this.commands.find(function(command) {687      return command._name === name;688    });689  }690 691  if (this._execs.has(name)) {692    return this.executeSubCommand(argv, args, parsed.unknown, subCommand ? subCommand._executableFile : undefined);693  }694 695  return result;696};697 698/**699 * Parse `argv`, setting options and invoking commands when defined.700 *701 * Use parseAsync instead of parse if any of your action handlers are async. Returns a Promise.702 *703 * @param {Array} argv704 * @return {Promise}705 * @api public706 */707Command.prototype.parseAsync = function(argv) {708  this.parse(argv);709  return Promise.all(this._actionResults);710};711 712/**713 * Execute a sub-command executable.714 *715 * @param {Array} argv716 * @param {Array} args717 * @param {Array} unknown718 * @param {String} executableFile719 * @api private720 */721 722Command.prototype.executeSubCommand = function(argv, args, unknown, executableFile) {723  args = args.concat(unknown);724 725  if (!args.length) this.help();726 727  var isExplicitJS = false; // Whether to use node to launch "executable"728 729  // executable730  var pm = argv[1];731  // name of the subcommand, like `pm-install`732  var bin = basename(pm, path.extname(pm)) + '-' + args[0];733  if (executableFile != null) {734    bin = executableFile;735    // Check for same extensions as we scan for below so get consistent launch behaviour.736    var executableExt = path.extname(executableFile);737    isExplicitJS = executableExt === '.js' || executableExt === '.ts' || executableExt === '.mjs';738  }739 740  // In case of globally installed, get the base dir where executable741  //  subcommand file should be located at742  var baseDir;743 744  var resolvedLink = fs.realpathSync(pm);745 746  baseDir = dirname(resolvedLink);747 748  // prefer local `./<bin>` to bin in the $PATH749  var localBin = path.join(baseDir, bin);750 751  // whether bin file is a js script with explicit `.js` or `.ts` extension752  if (exists(localBin + '.js')) {753    bin = localBin + '.js';754    isExplicitJS = true;755  } else if (exists(localBin + '.ts')) {756    bin = localBin + '.ts';757    isExplicitJS = true;758  } else if (exists(localBin + '.mjs')) {759    bin = localBin + '.mjs';760    isExplicitJS = true;761  } else if (exists(localBin)) {762    bin = localBin;763  }764 765  args = args.slice(1);766 767  var proc;768  if (process.platform !== 'win32') {769    if (isExplicitJS) {770      args.unshift(bin);771      // add executable arguments to spawn772      args = incrementNodeInspectorPort(process.execArgv).concat(args);773 774      proc = spawn(process.argv[0], args, { stdio: 'inherit' });775    } else {776      proc = spawn(bin, args, { stdio: 'inherit' });777    }778  } else {779    args.unshift(bin);780    // add executable arguments to spawn781    args = incrementNodeInspectorPort(process.execArgv).concat(args);782    proc = spawn(process.execPath, args, { stdio: 'inherit' });783  }784 785  var signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP'];786  signals.forEach(function(signal) {787    process.on(signal, function() {788      if (proc.killed === false && proc.exitCode === null) {789        proc.kill(signal);790      }791    });792  });793 794  // By default terminate process when spawned process terminates.795  // Suppressing the exit if exitCallback defined is a bit messy and of limited use, but does allow process to stay running!796  const exitCallback = this._exitCallback;797  if (!exitCallback) {798    proc.on('close', process.exit.bind(process));799  } else {800    proc.on('close', () => {801      exitCallback(new CommanderError(process.exitCode || 0, 'commander.executeSubCommandAsync', '(close)'));802    });803  }804  proc.on('error', function(err) {805    if (err.code === 'ENOENT') {806      console.error('error: %s(1) does not exist, try --help', bin);807    } else if (err.code === 'EACCES') {808      console.error('error: %s(1) not executable. try chmod or run with root', bin);809    }810    if (!exitCallback) {811      process.exit(1);812    } else {813      const wrappedError = new CommanderError(1, 'commander.executeSubCommandAsync', '(error)');814      wrappedError.nestedError = err;815      exitCallback(wrappedError);816    }817  });818 819  // Store the reference to the child process820  this.runningCommand = proc;821};822 823/**824 * Normalize `args`, splitting joined short flags. For example825 * the arg "-abc" is equivalent to "-a -b -c".826 * This also normalizes equal sign and splits "--abc=def" into "--abc def".827 *828 * @param {Array} args829 * @return {Array}830 * @api private831 */832 833Command.prototype.normalize = function(args) {834  var ret = [],835    arg,836    lastOpt,837    index,838    short,839    opt;840 841  for (var i = 0, len = args.length; i < len; ++i) {842    arg = args[i];843    if (i > 0) {844      lastOpt = this.optionFor(args[i - 1]);845    }846 847    if (arg === '--') {848      // Honor option terminator849      ret = ret.concat(args.slice(i));850      break;851    } else if (lastOpt && lastOpt.required) {852      ret.push(arg);853    } else if (arg.length > 2 && arg[0] === '-' && arg[1] !== '-') {854      short = arg.slice(0, 2);855      opt = this.optionFor(short);856      if (opt && (opt.required || opt.optional)) {857        ret.push(short);858        ret.push(arg.slice(2));859      } else {860        arg.slice(1).split('').forEach(function(c) {861          ret.push('-' + c);862        });863      }864    } else if (/^--/.test(arg) && ~(index = arg.indexOf('='))) {865      ret.push(arg.slice(0, index), arg.slice(index + 1));866    } else {867      ret.push(arg);868    }869  }870 871  return ret;872};873 874/**875 * Parse command `args`.876 *877 * When listener(s) are available those878 * callbacks are invoked, otherwise the "*"879 * event is emitted and those actions are invoked.880 *881 * @param {Array} args882 * @return {Command} for chaining883 * @api private884 */885 886Command.prototype.parseArgs = function(args, unknown) {887  var name;888 889  if (args.length) {890    name = args[0];891    if (this.listeners('command:' + name).length) {892      this.emit('command:' + args.shift(), args, unknown);893    } else {894      this.emit('command:*', args, unknown);895    }896  } else {897    outputHelpIfRequested(this, unknown);898 899    // If there were no args and we have unknown options,900    // then they are extraneous and we need to error.901    if (unknown.length > 0 && !this.defaultExecutable) {902      this.unknownOption(unknown[0]);903    }904    if (this.commands.length === 0 &&905        this._args.filter(function(a) { return a.required; }).length === 0) {906      this.emit('command:*');907    }908  }909 910  return this;911};912 913/**914 * Return an option matching `arg` if any.915 *916 * @param {String} arg917 * @return {Option}918 * @api private919 */920 921Command.prototype.optionFor = function(arg) {922  for (var i = 0, len = this.options.length; i < len; ++i) {923    if (this.options[i].is(arg)) {924      return this.options[i];925    }926  }927};928 929/**930 * Display an error message if a mandatory option does not have a value.931 *932 * @api private933 */934 935Command.prototype._checkForMissingMandatoryOptions = function() {936  // Walk up hierarchy so can call from action handler after checking for displaying help.937  for (var cmd = this; cmd; cmd = cmd.parent) {938    cmd.options.forEach((anOption) => {939      if (anOption.mandatory && (cmd._getOptionValue(anOption.attributeName()) === undefined)) {940        cmd.missingMandatoryOptionValue(anOption);941      }942    });943  }944};945 946/**947 * Parse options from `argv` returning `argv`948 * void of these options.949 *950 * @param {Array} argv951 * @return {{args: Array, unknown: Array}}952 * @api public953 */954 955Command.prototype.parseOptions = function(argv) {956  var args = [],957    len = argv.length,958    literal,959    option,960    arg;961 962  var unknownOptions = [];963 964  // parse options965  for (var i = 0; i < len; ++i) {966    arg = argv[i];967 968    // literal args after --969    if (literal) {970      args.push(arg);971      continue;972    }973 974    if (arg === '--') {975      literal = true;976      continue;977    }978 979    // find matching Option980    option = this.optionFor(arg);981 982    // option is defined983    if (option) {984      // requires arg985      if (option.required) {986        arg = argv[++i];987        if (arg == null) return this.optionMissingArgument(option);988        this.emit('option:' + option.name(), arg);989      // optional arg990      } else if (option.optional) {991        arg = argv[i + 1];992        if (arg == null || (arg[0] === '-' && arg !== '-')) {993          arg = null;994        } else {995          ++i;996        }997        this.emit('option:' + option.name(), arg);998      // flag999      } else {1000        this.emit('option:' + option.name());1001      }1002      continue;1003    }1004 1005    // looks like an option1006    if (arg.length > 1 && arg[0] === '-') {1007      unknownOptions.push(arg);1008 1009      // If the next argument looks like it might be1010      // an argument for this option, we pass it on.1011      // If it isn't, then it'll simply be ignored1012      if ((i + 1) < argv.length && (argv[i + 1][0] !== '-' || argv[i + 1] === '-')) {1013        unknownOptions.push(argv[++i]);1014      }1015      continue;1016    }1017 1018    // arg1019    args.push(arg);1020  }1021 1022  return { args: args, unknown: unknownOptions };1023};1024 1025/**1026 * Return an object containing options as key-value pairs1027 *1028 * @return {Object}1029 * @api public1030 */1031Command.prototype.opts = function() {1032  if (this._storeOptionsAsProperties) {1033    // Preserve original behaviour so backwards compatible when still using properties1034    var result = {},1035      len = this.options.length;1036 1037    for (var i = 0; i < len; i++) {1038      var key = this.options[i].attributeName();1039      result[key] = key === this._versionOptionName ? this._version : this[key];1040    }1041    return result;1042  }1043 1044  return this._optionValues;1045};1046 1047/**1048 * Argument `name` is missing.1049 *1050 * @param {String} name1051 * @api private1052 */1053 1054Command.prototype.missingArgument = function(name) {1055  const message = `error: missing required argument '${name}'`;1056  console.error(message);1057  this._exit(1, 'commander.missingArgument', message);1058};1059 1060/**1061 * `Option` is missing an argument, but received `flag` or nothing.1062 *1063 * @param {Option} option1064 * @param {String} [flag]1065 * @api private1066 */1067 1068Command.prototype.optionMissingArgument = function(option, flag) {1069  let message;1070  if (flag) {1071    message = `error: option '${option.flags}' argument missing, got '${flag}'`;1072  } else {1073    message = `error: option '${option.flags}' argument missing`;1074  }1075  console.error(message);1076  this._exit(1, 'commander.optionMissingArgument', message);1077};1078 1079/**1080 * `Option` does not have a value, and is a mandatory option.1081 *1082 * @param {Option} option1083 * @api private1084 */1085 1086Command.prototype.missingMandatoryOptionValue = function(option) {1087  const message = `error: required option '${option.flags}' not specified`;1088  console.error(message);1089  this._exit(1, 'commander.missingMandatoryOptionValue', message);1090};1091 1092/**1093 * Unknown option `flag`.1094 *1095 * @param {String} flag1096 * @api private1097 */1098 1099Command.prototype.unknownOption = function(flag) {1100  if (this._allowUnknownOption) return;1101  const message = `error: unknown option '${flag}'`;1102  console.error(message);1103  this._exit(1, 'commander.unknownOption', message);1104};1105 1106/**1107 * Variadic argument with `name` is not the last argument as required.1108 *1109 * @param {String} name1110 * @api private1111 */1112 1113Command.prototype.variadicArgNotLast = function(name) {1114  const message = `error: variadic arguments must be last '${name}'`;1115  console.error(message);1116  this._exit(1, 'commander.variadicArgNotLast', message);1117};1118 1119/**1120 * Set the program version to `str`.1121 *1122 * This method auto-registers the "-V, --version" flag1123 * which will print the version number when passed.1124 *1125 * You can optionally supply the  flags and description to override the defaults.1126 *1127 * @param {String} str1128 * @param {String} [flags]1129 * @param {String} [description]1130 * @return {Command} for chaining1131 * @api public1132 */1133 1134Command.prototype.version = function(str, flags, description) {1135  if (arguments.length === 0) return this._version;1136  this._version = str;1137  flags = flags || '-V, --version';1138  description = description || 'output the version number';1139  var versionOption = new Option(flags, description);1140  this._versionOptionName = versionOption.long.substr(2) || 'version';1141  this.options.push(versionOption);1142  var self = this;1143  this.on('option:' + this._versionOptionName, function() {1144    process.stdout.write(str + '\n');1145    self._exit(0, 'commander.version', str);1146  });1147  return this;1148};1149 1150/**1151 * Set the description to `str`.1152 *1153 * @param {String} str1154 * @param {Object} [argsDescription]1155 * @return {String|Command}1156 * @api public1157 */1158 1159Command.prototype.description = function(str, argsDescription) {1160  if (arguments.length === 0) return this._description;1161  this._description = str;1162  this._argsDescription = argsDescription;1163  return this;1164};1165 1166/**1167 * Set an alias for the command1168 *1169 * @param {String} alias1170 * @return {String|Command}1171 * @api public1172 */1173 1174Command.prototype.alias = function(alias) {1175  var command = this;1176  if (this.commands.length !== 0) {1177    command = this.commands[this.commands.length - 1];1178  }1179 1180  if (arguments.length === 0) return command._alias;1181 1182  if (alias === command._name) throw new Error('Command alias can\'t be the same as its name');1183 1184  command._alias = alias;1185  return this;1186};1187 1188/**1189 * Set / get the command usage `str`.1190 *1191 * @param {String} [str]1192 * @return {String|Command}1193 * @api public1194 */1195 1196Command.prototype.usage = function(str) {1197  var args = this._args.map(function(arg) {1198    return humanReadableArgName(arg);1199  });1200 

Showing the first 1,200 of 1650 lines. Download the file for the rest.