| 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;
|
|---|