1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 |
1×
1×
48×
44×
48×
48×
48×
48×
48×
48×
48×
48×
48×
48×
48×
48×
47×
1×
11×
11×
1×
43×
38×
1×
9×
9×
1×
53×
53×
53×
53×
43×
10×
53×
53×
2×
51×
2×
2×
51×
51×
49×
42×
41×
40×
37×
1×
40×
4×
1×
4×
4×
4×
4×
1× | #!/usr/bin/node
var Option = require('./Option'),
Flag = require('./Flag'),
Command = require('./Command'),
CommandGroup = require('./CommandGroup'),
helpers = require('./Helpers'),
ConfigError = require('./error/config'),
InvalidInputError = require('./error/invalid-input');
/**
* Cli Constructor
*
* Create a new Cli Object, pass in options to configure the base Cli.
*
* Options (type, default value):
*
* * scriptName (string, null) - The name of cli script, this is automatically parsed, but use this as an override. Used in displaying documentation.
* * verboseEnabled (boolean, true) - Automatically parse -v, -vv, -vvv, and --verbose
*
* @param cliOptions
* @constructor
*/
function Cli(cliOptions) {
if (cliOptions === undefined) {
cliOptions = {};
}
this.description = cliOptions.description || '';
this.scriptName = cliOptions.scriptName;
this.verboseEnabled = (cliOptions.verboseEnabled !== undefined) ? cliOptions.verboseEnabled : true;
this.helpEnabled = (cliOptions.helpEnabled !== undefined) ? cliOptions.helpEnabled : true;
this.helpOnNoArgs = (cliOptions.helpOnNoArgs !== undefined) ? cliOptions.helpOnNoArgs : true;
this.exitOnHelp = (cliOptions.exitOnHelp !== undefined) ? cliOptions.exitOnHelp : false;
this.allowExtraArgs = (cliOptions.allowExtraArgs !== undefined) ? cliOptions.allowExtraArgs : false;
this.params = {};
this.options = [];
this.flags = [];
this.commandGroups = [];
if (this.verboseEnabled) {
this.params.verbose = 0;
}
}
/**
* Add Command Group
*
* Create a command group and add it to the config.
* @param {{name, [description], commands, [callback] [required]}} options
*
* @see CommandGroup
* @returns {Cli}
*/
Cli.prototype.commandGroup = function (options) {
this.commandGroups.push(new CommandGroup(options));
return this;
};
/**
* Add Option
*
* Adds an Option to the CLI to be checked during the parse() method. See Option for more info.
* @param {{name, description, [shortFlag], [longFlag], [type], [length]}} options
*
* @see Option
* @returns {Cli}
*/
Cli.prototype.option = function (options) {
this.options.push(new Option(options));
return this;
};
/**
* Add Flag
*
* Adds a Flag to the CLI to be checked during the parse() method. See Flag for more info.
* @param {{name, [description], short, [long], [value]}} options
* @see Flag
* @returns {Cli}
*/
Cli.prototype.flag = function (options) {
this.flags.push(new Flag(options));
return this;
};
/**
* Parse
*
* Take the arguments (or array passed) and parse it into the params object.
* @param {String[]} [args] An optional array of args, the process.argv is used by default.
* @returns {Object}
* @throws ConfigError
* @throws InvalidInputError
*/
Cli.prototype.parse = function (args) {
Iif (args == undefined) {
args = process.argv;
}
var helpCalled = false;
//Pull off the node path
args.shift();
//Parse Script Name
if (this.scriptName == null) {
this.scriptName = args.shift();
}
else {
args.shift();
}
this.params = {};
if (args.length === 0 && this.helpOnNoArgs) {
return this.getHelpText();
}
//Parse flags - Make sure we grab help text first
var flagParams = Flag.parse(args, this.flags, {
verboseEnabled: this.verboseEnabled,
helpEnabled: this.helpEnabled,
allowExtra: this.allowExtraArgs
},
function () {
this.getHelpText();
helpCalled = true;
}.bind(this)
);
helpers.merge(this.params, flagParams);
if (!helpCalled) {
//Parse Option
helpers.merge(this.params, Option.parse(args, this.options));
//Parse Command Groups
helpers.merge(this.params, CommandGroup.parse(args, this.commandGroups));
if (!this.allowExtraArgs) {
this.checkForExtras(args);
}
return this.params;
}
};
/**
* Check For Extras
*
* Checks for remaining args and throws an error.
* @throws InvalidInputError
* @param args
*/
Cli.prototype.checkForExtras = function (args) {
if (args.length) {
throw new InvalidInputError("Invalid extra params supplied: " + args.join(', '));
}
};
Cli.prototype.getHelpText = function () {
var TtyParser = require('./output-parsers/tty');
var ttyParser = new TtyParser(this);
ttyParser.output();
Iif (this.exitOnHelp) {
process.exit(3);
}
};
module.exports = Cli; |