l0bsterssg

node.js static responsive blog post generator
Log | Files | Refs | README

subparsers.js (3590B)


      1 /** internal
      2  * class ActionSubparsers
      3  *
      4  * Support the creation of such sub-commands with the addSubparsers()
      5  *
      6  * This class inherited from [[Action]]
      7  **/
      8 'use strict';
      9 
     10 var util    = require('util');
     11 var format  = require('util').format;
     12 
     13 
     14 var Action = require('../action');
     15 
     16 // Constants
     17 var c = require('../const');
     18 
     19 // Errors
     20 var argumentErrorHelper = require('../argument/error');
     21 
     22 
     23 /*:nodoc:*
     24  * new ChoicesPseudoAction(name, help)
     25  *
     26  * Create pseudo action for correct help text
     27  *
     28  **/
     29 function ChoicesPseudoAction(name, help) {
     30   var options = {
     31     optionStrings: [],
     32     dest: name,
     33     help: help
     34   };
     35 
     36   Action.call(this, options);
     37 }
     38 
     39 util.inherits(ChoicesPseudoAction, Action);
     40 
     41 /**
     42  * new ActionSubparsers(options)
     43  * - options (object): options hash see [[Action.new]]
     44  *
     45  **/
     46 function ActionSubparsers(options) {
     47   options = options || {};
     48   options.dest = options.dest || c.SUPPRESS;
     49   options.nargs = c.PARSER;
     50 
     51   this.debug = (options.debug === true);
     52 
     53   this._progPrefix = options.prog;
     54   this._parserClass = options.parserClass;
     55   this._nameParserMap = {};
     56   this._choicesActions = [];
     57 
     58   options.choices = this._nameParserMap;
     59   Action.call(this, options);
     60 }
     61 
     62 util.inherits(ActionSubparsers, Action);
     63 
     64 /*:nodoc:*
     65  * ActionSubparsers#addParser(name, options) -> ArgumentParser
     66  * - name (string): sub-command name
     67  * - options (object): see [[ArgumentParser.new]]
     68  *
     69  *  Note:
     70  *  addParser supports an additional aliases option,
     71  *  which allows multiple strings to refer to the same subparser.
     72  *  This example, like svn, aliases co as a shorthand for checkout
     73  *
     74  **/
     75 ActionSubparsers.prototype.addParser = function (name, options) {
     76   var parser;
     77 
     78   var self = this;
     79 
     80   options = options || {};
     81 
     82   options.debug = (this.debug === true);
     83 
     84   // set program from the existing prefix
     85   if (!options.prog) {
     86     options.prog = this._progPrefix + ' ' + name;
     87   }
     88 
     89   var aliases = options.aliases || [];
     90 
     91   // create a pseudo-action to hold the choice help
     92   if (!!options.help || typeof options.help === 'string') {
     93     var help = options.help;
     94     delete options.help;
     95 
     96     var choiceAction = new ChoicesPseudoAction(name, help);
     97     this._choicesActions.push(choiceAction);
     98   }
     99 
    100   // create the parser and add it to the map
    101   parser = new this._parserClass(options);
    102   this._nameParserMap[name] = parser;
    103 
    104   // make parser available under aliases also
    105   aliases.forEach(function (alias) {
    106     self._nameParserMap[alias] = parser;
    107   });
    108 
    109   return parser;
    110 };
    111 
    112 ActionSubparsers.prototype._getSubactions = function () {
    113   return this._choicesActions;
    114 };
    115 
    116 /*:nodoc:*
    117  * ActionSubparsers#call(parser, namespace, values, optionString) -> Void
    118  * - parser (ArgumentParser): current parser
    119  * - namespace (Namespace): namespace for output data
    120  * - values (Array): parsed values
    121  * - optionString (Array): input option string(not parsed)
    122  *
    123  * Call the action. Parse input aguments
    124  **/
    125 ActionSubparsers.prototype.call = function (parser, namespace, values) {
    126   var parserName = values[0];
    127   var argStrings = values.slice(1);
    128 
    129   // set the parser name if requested
    130   if (this.dest !== c.SUPPRESS) {
    131     namespace[this.dest] = parserName;
    132   }
    133 
    134   // select the parser
    135   if (this._nameParserMap[parserName]) {
    136     parser = this._nameParserMap[parserName];
    137   } else {
    138     throw argumentErrorHelper(format(
    139       'Unknown parser "%s" (choices: [%s]).',
    140         parserName,
    141         Object.keys(this._nameParserMap).join(', ')
    142     ));
    143   }
    144 
    145   // parse all the remaining options into the namespace
    146   parser.parseArgs(argStrings, namespace);
    147 };
    148 
    149 module.exports = ActionSubparsers;