/** internal * class ActionSubparsers * * Support the creation of such sub-commands with the addSubparsers() * * This class inherited from [[Action]] **/ 'use strict'; var util = require('util'); var format = require('util').format; var Action = require('../action'); // Constants var c = require('../const'); // Errors var argumentErrorHelper = require('../argument/error'); /*:nodoc:* * new ChoicesPseudoAction(name, help) * * Create pseudo action for correct help text * **/ function ChoicesPseudoAction(name, help) { var options = { optionStrings: [], dest: name, help: help }; Action.call(this, options); } util.inherits(ChoicesPseudoAction, Action); /** * new ActionSubparsers(options) * - options (object): options hash see [[Action.new]] * **/ function ActionSubparsers(options) { options = options || {}; options.dest = options.dest || c.SUPPRESS; options.nargs = c.PARSER; this.debug = (options.debug === true); this._progPrefix = options.prog; this._parserClass = options.parserClass; this._nameParserMap = {}; this._choicesActions = []; options.choices = this._nameParserMap; Action.call(this, options); } util.inherits(ActionSubparsers, Action); /*:nodoc:* * ActionSubparsers#addParser(name, options) -> ArgumentParser * - name (string): sub-command name * - options (object): see [[ArgumentParser.new]] * * Note: * addParser supports an additional aliases option, * which allows multiple strings to refer to the same subparser. * This example, like svn, aliases co as a shorthand for checkout * **/ ActionSubparsers.prototype.addParser = function (name, options) { var parser; var self = this; options = options || {}; options.debug = (this.debug === true); // set program from the existing prefix if (!options.prog) { options.prog = this._progPrefix + ' ' + name; } var aliases = options.aliases || []; // create a pseudo-action to hold the choice help if (!!options.help || typeof options.help === 'string') { var help = options.help; delete options.help; var choiceAction = new ChoicesPseudoAction(name, help); this._choicesActions.push(choiceAction); } // create the parser and add it to the map parser = new this._parserClass(options); this._nameParserMap[name] = parser; // make parser available under aliases also aliases.forEach(function (alias) { self._nameParserMap[alias] = parser; }); return parser; }; ActionSubparsers.prototype._getSubactions = function () { return this._choicesActions; }; /*:nodoc:* * ActionSubparsers#call(parser, namespace, values, optionString) -> Void * - parser (ArgumentParser): current parser * - namespace (Namespace): namespace for output data * - values (Array): parsed values * - optionString (Array): input option string(not parsed) * * Call the action. Parse input aguments **/ ActionSubparsers.prototype.call = function (parser, namespace, values) { var parserName = values[0]; var argStrings = values.slice(1); // set the parser name if requested if (this.dest !== c.SUPPRESS) { namespace[this.dest] = parserName; } // select the parser if (this._nameParserMap[parserName]) { parser = this._nameParserMap[parserName]; } else { throw argumentErrorHelper(format( 'Unknown parser "%s" (choices: [%s]).', parserName, Object.keys(this._nameParserMap).join(', ') )); } // parse all the remaining options into the namespace parser.parseArgs(argStrings, namespace); }; module.exports = ActionSubparsers;