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