149 lines
3.5 KiB
JavaScript
149 lines
3.5 KiB
JavaScript
/** 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;
|