150 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			150 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; |