coa 0.4.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +28 -33
- package/README.ru.md +316 -0
- package/index.js +1 -1
- package/lib/arg.js +44 -161
- package/lib/cmd.js +434 -547
- package/lib/coaobject.js +100 -0
- package/lib/coaparam.js +125 -0
- package/lib/color.js +19 -22
- package/lib/completion.js +161 -119
- package/lib/index.js +14 -10
- package/lib/opt.js +130 -313
- package/lib/shell.js +13 -13
- package/package.json +21 -17
- package/.npmignore +0 -6
- package/.travis.yml +0 -11
- package/GNUmakefile +0 -34
- package/src/arg.coffee +0 -130
- package/src/cmd.coffee +0 -456
- package/src/color.coffee +0 -25
- package/src/completion.coffee +0 -158
- package/src/index.coffee +0 -5
- package/src/opt.coffee +0 -243
- package/src/shell.coffee +0 -10
- package/test/coa.js +0 -496
- package/test/common.js +0 -1
- package/test/mocha.opts +0 -3
- package/test/shell-test.js +0 -60
- package/tests/api-h.js +0 -9
- package/tests/h.js +0 -6
package/lib/opt.js
CHANGED
@@ -1,338 +1,155 @@
|
|
1
|
-
|
2
|
-
var Cmd, Color, Opt, Q, fs;
|
1
|
+
'use strict';
|
3
2
|
|
4
|
-
|
3
|
+
const
|
4
|
+
Q = require('q'),
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
Color = require('./color').Color;
|
9
|
-
|
10
|
-
Cmd = require('./cmd').Cmd;
|
6
|
+
CoaParam = require('./coaparam'),
|
7
|
+
Color = require('./color');
|
11
8
|
|
12
9
|
/**
|
13
|
-
Option
|
14
|
-
|
15
|
-
Named entity. Options may have short and long keys for use from command line.
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
exports
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
@returns {COA.Opt} this instance (for chainability)
|
36
|
-
*/
|
37
|
-
|
38
|
-
|
39
|
-
Opt.prototype.name = function(_name) {
|
40
|
-
this._name = _name;
|
41
|
-
return this;
|
42
|
-
};
|
43
|
-
|
44
|
-
/**
|
45
|
-
Set a long description for option to be used anywhere in text messages.
|
46
|
-
@param {String} _title option title
|
47
|
-
@returns {COA.Opt} this instance (for chainability)
|
48
|
-
*/
|
49
|
-
|
50
|
-
|
51
|
-
Opt.prototype.title = Cmd.prototype.title;
|
52
|
-
|
53
|
-
/**
|
54
|
-
Set a short key for option to be used with one hyphen from command line.
|
55
|
-
@param {String} _short
|
56
|
-
@returns {COA.Opt} this instance (for chainability)
|
57
|
-
*/
|
58
|
-
|
59
|
-
|
60
|
-
Opt.prototype.short = function(_short) {
|
61
|
-
this._short = _short;
|
62
|
-
return this._cmd._optsByKey['-' + _short] = this;
|
63
|
-
};
|
64
|
-
|
65
|
-
/**
|
66
|
-
Set a short key for option to be used with double hyphens from command line.
|
67
|
-
@param {String} _long
|
68
|
-
@returns {COA.Opt} this instance (for chainability)
|
69
|
-
*/
|
70
|
-
|
71
|
-
|
72
|
-
Opt.prototype.long = function(_long) {
|
73
|
-
this._long = _long;
|
74
|
-
return this._cmd._optsByKey['--' + _long] = this;
|
75
|
-
};
|
76
|
-
|
77
|
-
/**
|
78
|
-
Make an option boolean, i.e. option without value.
|
79
|
-
@returns {COA.Opt} this instance (for chainability)
|
80
|
-
*/
|
81
|
-
|
82
|
-
|
83
|
-
Opt.prototype.flag = function() {
|
84
|
-
this._flag = true;
|
85
|
-
return this;
|
86
|
-
};
|
87
|
-
|
88
|
-
/**
|
89
|
-
Makes an option accepts multiple values.
|
90
|
-
Otherwise, the value will be used by the latter passed.
|
91
|
-
@returns {COA.Opt} this instance (for chainability)
|
92
|
-
*/
|
93
|
-
|
94
|
-
|
95
|
-
Opt.prototype.arr = function() {
|
96
|
-
this._arr = true;
|
97
|
-
return this;
|
98
|
-
};
|
99
|
-
|
100
|
-
/**
|
101
|
-
Makes an option required.
|
102
|
-
@returns {COA.Opt} this instance (for chainability)
|
103
|
-
*/
|
104
|
-
|
105
|
-
|
106
|
-
Opt.prototype.req = function() {
|
107
|
-
this._req = true;
|
108
|
-
return this;
|
109
|
-
};
|
110
|
-
|
111
|
-
/**
|
112
|
-
Makes an option to act as a command,
|
113
|
-
i.e. program will exit just after option action.
|
114
|
-
@returns {COA.Opt} this instance (for chainability)
|
115
|
-
*/
|
116
|
-
|
117
|
-
|
118
|
-
Opt.prototype.only = function() {
|
119
|
-
this._only = true;
|
120
|
-
return this;
|
121
|
-
};
|
10
|
+
* Option
|
11
|
+
*
|
12
|
+
* Named entity. Options may have short and long keys for use from command line.
|
13
|
+
*
|
14
|
+
* @namespace
|
15
|
+
* @class Opt
|
16
|
+
* @extends CoaParam
|
17
|
+
*/
|
18
|
+
module.exports = class Opt extends CoaParam {
|
19
|
+
/**
|
20
|
+
* @constructs
|
21
|
+
* @param {COA.Cmd} cmd - parent command
|
22
|
+
*/
|
23
|
+
constructor(cmd) {
|
24
|
+
super(cmd);
|
25
|
+
|
26
|
+
this._short = null;
|
27
|
+
this._long = null;
|
28
|
+
this._flag = false;
|
29
|
+
this._only = false;
|
30
|
+
this._cmd._opts.push(this);
|
31
|
+
}
|
122
32
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
33
|
+
/**
|
34
|
+
* Set a short key for option to be used with one hyphen from command line.
|
35
|
+
*
|
36
|
+
* @param {String} short - short name
|
37
|
+
* @returns {COA.Opt} - this instance (for chainability)
|
38
|
+
*/
|
39
|
+
short(short) {
|
40
|
+
this._short = short;
|
41
|
+
this._cmd._optsByKey[`-${short}`] = this;
|
42
|
+
return this;
|
43
|
+
}
|
132
44
|
|
45
|
+
/**
|
46
|
+
* Set a short key for option to be used with double hyphens from command line.
|
47
|
+
*
|
48
|
+
* @param {String} long - long name
|
49
|
+
* @returns {COA.Opt} - this instance (for chainability)
|
50
|
+
*/
|
51
|
+
long(long) {
|
52
|
+
this._long = long;
|
53
|
+
this._cmd._optsByKey[`--${long}`] = this;
|
54
|
+
return this;
|
55
|
+
}
|
133
56
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
57
|
+
/**
|
58
|
+
* Make an option boolean, i.e. option without value.
|
59
|
+
*
|
60
|
+
* @returns {COA.Opt} - this instance (for chainability)
|
61
|
+
*/
|
62
|
+
flag() {
|
63
|
+
this._flag = true;
|
64
|
+
return this;
|
65
|
+
}
|
138
66
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
67
|
+
/**
|
68
|
+
* Makes an option to act as a command,
|
69
|
+
* i.e. program will exit just after option action.
|
70
|
+
*
|
71
|
+
* @returns {COA.Opt} - this instance (for chainability)
|
72
|
+
*/
|
73
|
+
only() {
|
74
|
+
this._only = true;
|
75
|
+
return this;
|
76
|
+
}
|
145
77
|
|
78
|
+
/**
|
79
|
+
* Add action for current option command.
|
80
|
+
* This action is performed if the current option
|
81
|
+
* is present in parsed options (with any value).
|
82
|
+
*
|
83
|
+
* @param {Function} act - action function,
|
84
|
+
* invoked in the context of command instance
|
85
|
+
* and has the parameters:
|
86
|
+
* - {Object} opts - parsed options
|
87
|
+
* - {Array} args - parsed arguments
|
88
|
+
* - {Object} res - actions result accumulator
|
89
|
+
* It can return rejected promise by Cmd.reject (in case of error)
|
90
|
+
* or any other value treated as result.
|
91
|
+
* @returns {COA.Opt} - this instance (for chainability)
|
92
|
+
*/
|
93
|
+
act(act) {
|
94
|
+
// Need function here for arguments
|
95
|
+
const opt = this;
|
96
|
+
this._cmd.act(function(opts) {
|
97
|
+
if(!opts.hasOwnProperty(opt._name)) return;
|
98
|
+
|
99
|
+
const res = act.apply(this, arguments);
|
100
|
+
if(!opt._only) return res;
|
101
|
+
|
102
|
+
return Q.when(res, out => this.reject({
|
103
|
+
toString : () => out.toString(),
|
104
|
+
exitCode : 0
|
105
|
+
}));
|
106
|
+
});
|
107
|
+
|
108
|
+
return this;
|
109
|
+
}
|
146
110
|
|
147
|
-
|
148
|
-
|
149
|
-
return this;
|
150
|
-
};
|
111
|
+
_saveVal(opts, val) {
|
112
|
+
this._val && (val = this._val(val));
|
151
113
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
*/
|
114
|
+
const name = this._name;
|
115
|
+
this._arr
|
116
|
+
? (opts[name] || (opts[name] = [])).push(val)
|
117
|
+
: (opts[name] = val);
|
157
118
|
|
119
|
+
return val;
|
120
|
+
}
|
158
121
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
var s;
|
163
|
-
if (typeof v === 'string') {
|
164
|
-
if (v === '-') {
|
165
|
-
return process.stdin;
|
166
|
-
} else {
|
167
|
-
s = fs.createReadStream(v, {
|
168
|
-
encoding: 'utf8'
|
169
|
-
});
|
170
|
-
s.pause();
|
171
|
-
return s;
|
172
|
-
}
|
173
|
-
} else {
|
174
|
-
return v;
|
175
|
-
}
|
176
|
-
});
|
177
|
-
};
|
122
|
+
_parse(argv, opts) {
|
123
|
+
return this._saveVal(opts, this._flag ? true : argv.shift());
|
124
|
+
}
|
178
125
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
@returns {COA.Opt} this instance (for chainability)
|
183
|
-
*/
|
126
|
+
_checkParsed(opts) {
|
127
|
+
return !opts.hasOwnProperty(this._name);
|
128
|
+
}
|
184
129
|
|
130
|
+
_usage() {
|
131
|
+
const res = [],
|
132
|
+
nameStr = this._name.toUpperCase();
|
185
133
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
return process.stdout;
|
191
|
-
} else {
|
192
|
-
return fs.createWriteStream(v, {
|
193
|
-
encoding: 'utf8'
|
194
|
-
});
|
134
|
+
if(this._short) {
|
135
|
+
res.push('-', Color('lgreen', this._short));
|
136
|
+
this._flag || res.push(' ' + nameStr);
|
137
|
+
res.push(', ');
|
195
138
|
}
|
196
|
-
} else {
|
197
|
-
return v;
|
198
|
-
}
|
199
|
-
});
|
200
|
-
};
|
201
|
-
|
202
|
-
/**
|
203
|
-
Add action for current option command.
|
204
|
-
This action is performed if the current option
|
205
|
-
is present in parsed options (with any value).
|
206
|
-
@param {Function} act action function,
|
207
|
-
invoked in the context of command instance
|
208
|
-
and has the parameters:
|
209
|
-
- {Object} opts parsed options
|
210
|
-
- {Array} args parsed arguments
|
211
|
-
- {Object} res actions result accumulator
|
212
|
-
It can return rejected promise by Cmd.reject (in case of error)
|
213
|
-
or any other value treated as result.
|
214
|
-
@returns {COA.Opt} this instance (for chainability)
|
215
|
-
*/
|
216
|
-
|
217
139
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
name = this._name;
|
222
|
-
this._cmd.act(function(opts) {
|
223
|
-
var res,
|
224
|
-
_this = this;
|
225
|
-
if (name in opts) {
|
226
|
-
res = act.apply(this, arguments);
|
227
|
-
if (opt._only) {
|
228
|
-
return Q.when(res, function(res) {
|
229
|
-
return _this.reject({
|
230
|
-
toString: function() {
|
231
|
-
return res.toString();
|
232
|
-
},
|
233
|
-
exitCode: 0
|
234
|
-
});
|
235
|
-
});
|
236
|
-
} else {
|
237
|
-
return res;
|
140
|
+
if(this._long) {
|
141
|
+
res.push('--', Color('green', this._long));
|
142
|
+
this._flag || res.push('=' + nameStr);
|
238
143
|
}
|
239
|
-
}
|
240
|
-
});
|
241
|
-
return this;
|
242
|
-
};
|
243
144
|
|
244
|
-
|
245
|
-
Set custom additional completion for current option.
|
246
|
-
@param {Function} completion generation function,
|
247
|
-
invoked in the context of option instance.
|
248
|
-
Accepts parameters:
|
249
|
-
- {Object} opts completion options
|
250
|
-
It can return promise or any other value treated as result.
|
251
|
-
@returns {COA.Opt} this instance (for chainability)
|
252
|
-
*/
|
145
|
+
res.push(' : ', this._title);
|
253
146
|
|
147
|
+
this._req && res.push(' ', Color('lred', '(required)'));
|
254
148
|
|
255
|
-
|
256
|
-
|
257
|
-
Opt.prototype._saveVal = function(opts, val) {
|
258
|
-
var _name;
|
259
|
-
if (this._val) {
|
260
|
-
val = this._val(val);
|
261
|
-
}
|
262
|
-
if (this._arr) {
|
263
|
-
(opts[_name = this._name] || (opts[_name] = [])).push(val);
|
264
|
-
} else {
|
265
|
-
opts[this._name] = val;
|
149
|
+
return res.join('');
|
266
150
|
}
|
267
|
-
return val;
|
268
|
-
};
|
269
|
-
|
270
|
-
Opt.prototype._parse = function(argv, opts) {
|
271
|
-
return this._saveVal(opts, this._flag ? true : argv.shift());
|
272
|
-
};
|
273
151
|
|
274
|
-
|
275
|
-
|
276
|
-
};
|
277
|
-
|
278
|
-
Opt.prototype._usage = function() {
|
279
|
-
var nameStr, res;
|
280
|
-
res = [];
|
281
|
-
nameStr = this._name.toUpperCase();
|
282
|
-
if (this._short) {
|
283
|
-
res.push('-', Color('lgreen', this._short));
|
284
|
-
if (!this._flag) {
|
285
|
-
res.push(' ' + nameStr);
|
286
|
-
}
|
287
|
-
res.push(', ');
|
288
|
-
}
|
289
|
-
if (this._long) {
|
290
|
-
res.push('--', Color('green', this._long));
|
291
|
-
if (!this._flag) {
|
292
|
-
res.push('=' + nameStr);
|
293
|
-
}
|
152
|
+
_requiredText() {
|
153
|
+
return `Missing required option:\n ${this._usage()}`;
|
294
154
|
}
|
295
|
-
|
296
|
-
if (this._req) {
|
297
|
-
res.push(' ', Color('lred', '(required)'));
|
298
|
-
}
|
299
|
-
return res.join('');
|
300
|
-
};
|
301
|
-
|
302
|
-
Opt.prototype._requiredText = function() {
|
303
|
-
return 'Missing required option:\n ' + this._usage();
|
304
|
-
};
|
305
|
-
|
306
|
-
/**
|
307
|
-
Return rejected promise with error code.
|
308
|
-
Use in .val() for return with error.
|
309
|
-
@param {Object} reject reason
|
310
|
-
You can customize toString() method and exitCode property
|
311
|
-
of reason object.
|
312
|
-
@returns {Q.promise} rejected promise
|
313
|
-
*/
|
314
|
-
|
315
|
-
|
316
|
-
Opt.prototype.reject = Cmd.prototype.reject;
|
317
|
-
|
318
|
-
/**
|
319
|
-
Finish chain for current option and return parent command instance.
|
320
|
-
@returns {COA.Cmd} parent command
|
321
|
-
*/
|
322
|
-
|
323
|
-
|
324
|
-
Opt.prototype.end = Cmd.prototype.end;
|
325
|
-
|
326
|
-
/**
|
327
|
-
Apply function with arguments in context of option instance.
|
328
|
-
@param {Function} fn
|
329
|
-
@param {Array} args
|
330
|
-
@returns {COA.Opt} this instance (for chainability)
|
331
|
-
*/
|
332
|
-
|
333
|
-
|
334
|
-
Opt.prototype.apply = Cmd.prototype.apply;
|
335
|
-
|
336
|
-
return Opt;
|
337
|
-
|
338
|
-
})();
|
155
|
+
};
|
package/lib/shell.js
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
|
2
|
-
exports.unescape = function(w) {
|
3
|
-
w = w.charAt(0) === '"' ? w.replace(/^"|([^\\])"$/g, '$1') : w.replace(/\\ /g, ' ');
|
4
|
-
return w.replace(/\\("|'|\$|`|\\)/g, '$1');
|
5
|
-
};
|
1
|
+
module.exports = { escape, unescape };
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
return w;
|
13
|
-
|
14
|
-
|
3
|
+
function unescape(w) {
|
4
|
+
w = w.charAt(0) === '"'
|
5
|
+
? w.replace(/^"|([^\\])"$/g, '$1')
|
6
|
+
: w.replace(/\\ /g, ' ');
|
7
|
+
|
8
|
+
return w.replace(/\\("|'|\$|`|\\)/g, '$1');
|
9
|
+
}
|
10
|
+
|
11
|
+
function escape(w) {
|
12
|
+
w = w.replace(/(["'$`\\])/g,'\\$1');
|
13
|
+
return w.match(/\s+/) ? `"${w}"` : w;
|
14
|
+
}
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "coa",
|
3
3
|
"description": "Command-Option-Argument: Yet another parser for command line options.",
|
4
|
-
"version": "0.
|
4
|
+
"version": "1.0.3",
|
5
5
|
"homepage": "http://github.com/veged/coa",
|
6
6
|
"author": "Sergey Berezhnoy <veged@ya.ru> (http://github.com/veged)",
|
7
7
|
"maintainers": [
|
@@ -11,6 +11,11 @@
|
|
11
11
|
"contributors": [
|
12
12
|
"Sergey Belov <peimei@ya.ru> (http://github.com/arikon)"
|
13
13
|
],
|
14
|
+
"files": [
|
15
|
+
"lib/",
|
16
|
+
"index.js",
|
17
|
+
"README.ru.md"
|
18
|
+
],
|
14
19
|
"repository": {
|
15
20
|
"type": "git",
|
16
21
|
"url": "git://github.com/veged/coa.git"
|
@@ -19,27 +24,26 @@
|
|
19
24
|
"lib": "./lib"
|
20
25
|
},
|
21
26
|
"dependencies": {
|
22
|
-
"q": "
|
27
|
+
"q": "^1.1.2"
|
23
28
|
},
|
24
29
|
"devDependencies": {
|
25
|
-
"
|
26
|
-
"
|
27
|
-
"
|
28
|
-
"
|
29
|
-
"mocha": "~1.
|
30
|
-
"
|
30
|
+
"chai": "~1.7.2",
|
31
|
+
"coveralls": "^2.11.16",
|
32
|
+
"eslint": "^3.15.0",
|
33
|
+
"eslint-config-pedant": "^0.8.0",
|
34
|
+
"mocha": "~1.21.4",
|
35
|
+
"nyc": "^10.1.2"
|
31
36
|
},
|
32
37
|
"scripts": {
|
33
|
-
"
|
34
|
-
"coverage": "
|
38
|
+
"clean": "rm -r .nyc_output coverage",
|
39
|
+
"coverage": "nyc --reporter=text --reporter=html mocha; echo; echo 'Open coverage/index.html file in your browser'",
|
40
|
+
"coveralls": "nyc report --reporter=text-lcov | coveralls",
|
41
|
+
"lint": "eslint .",
|
42
|
+
"pretest": "npm run lint",
|
43
|
+
"test": "nyc mocha"
|
35
44
|
},
|
36
45
|
"engines": {
|
37
|
-
"node": ">=
|
46
|
+
"node": ">= 4.0"
|
38
47
|
},
|
39
|
-
"
|
40
|
-
{
|
41
|
-
"type": "MIT"
|
42
|
-
}
|
43
|
-
],
|
44
|
-
"optionalDependencies": {}
|
48
|
+
"license": "MIT"
|
45
49
|
}
|
package/.npmignore
DELETED
package/.travis.yml
DELETED
package/GNUmakefile
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
BIN = ./node_modules/.bin
|
2
|
-
|
3
|
-
.PHONY: all
|
4
|
-
all: lib
|
5
|
-
|
6
|
-
lib: $(foreach s,$(wildcard src/*.coffee),$(patsubst src/%.coffee,lib/%.js,$s))
|
7
|
-
|
8
|
-
lib-cov: clean-coverage lib
|
9
|
-
$(BIN)/istanbul instrument --output lib-cov --no-compact --variable global.__coverage__ lib
|
10
|
-
|
11
|
-
lib/%.js: src/%.coffee
|
12
|
-
$(BIN)/coffee -cb -o $(@D) $<
|
13
|
-
|
14
|
-
.PHONY: test
|
15
|
-
test: lib
|
16
|
-
$(BIN)/mocha
|
17
|
-
|
18
|
-
.PHONY: coverage
|
19
|
-
coverage: lib-cov
|
20
|
-
COVER=1 $(BIN)/mocha --reporter mocha-istanbul
|
21
|
-
@echo
|
22
|
-
@echo Open html-report/index.html file in your browser
|
23
|
-
|
24
|
-
.PHONY: watch
|
25
|
-
watch:
|
26
|
-
$(BIN)/coffee --watch --bare --output lib src/*.coffee
|
27
|
-
|
28
|
-
.PHONY: clean
|
29
|
-
clean: clean-coverage
|
30
|
-
|
31
|
-
.PHONY: clean-coverage
|
32
|
-
clean-coverage:
|
33
|
-
-rm -rf lib-cov
|
34
|
-
-rm -rf html-report
|