coa 0.3.9 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
package/.npmignore CHANGED
@@ -1,5 +1,6 @@
1
1
  .idea
2
2
  *.iml
3
3
  node_modules/
4
+ !node_modules/coa*.js
4
5
  lib-cov/
5
6
  html-report/
package/.travis.yml CHANGED
@@ -1,10 +1,11 @@
1
1
  language: node_js
2
2
 
3
3
  node_js:
4
- - 0.6
5
- - 0.8
6
- - 0.9
4
+ - "0.6"
5
+ - "0.8"
6
+ - "0.10"
7
+ - "0.11"
7
8
 
8
9
  matrix:
9
10
  allow_failures:
10
- - node_js: 0.9
11
+ - node_js: 0.11
package/README.md CHANGED
@@ -227,6 +227,11 @@ Default value passed through validation function as ordinary value.<br>
227
227
  **@param** *Object* `_def`<br>
228
228
  **@returns** *COA.Opt* `this` instance (for chainability)
229
229
 
230
+ #### Opt.input
231
+ Make option value inputting stream.
232
+ It's add useful validation and shortcut for STDIN.
233
+ **@returns** *{COA.Opt}* `this` instance (for chainability)
234
+
230
235
  #### Opt.output
231
236
  Make option value outputing stream.<br>
232
237
  It's add useful validation and shortcut for STDOUT.<br>
package/lib/arg.js CHANGED
@@ -1,4 +1,4 @@
1
- // Generated by CoffeeScript 1.4.0
1
+ // Generated by CoffeeScript 1.6.3
2
2
  var Arg, Cmd, Color, Opt;
3
3
 
4
4
  Color = require('./color').Color;
package/lib/cmd.js CHANGED
@@ -1,4 +1,4 @@
1
- // Generated by CoffeeScript 1.4.0
1
+ // Generated by CoffeeScript 1.6.3
2
2
  var Cmd, Color, PATH, Q, UTIL,
3
3
  __slice = [].slice;
4
4
 
@@ -35,6 +35,7 @@ exports.Cmd = Cmd = (function() {
35
35
  this._opts = [];
36
36
  this._optsByKey = {};
37
37
  this._args = [];
38
+ this._ext = false;
38
39
  }
39
40
 
40
41
  Cmd.get = function(propertyName, func) {
@@ -70,10 +71,13 @@ exports.Cmd = Cmd = (function() {
70
71
  });
71
72
 
72
73
  Cmd.prototype._parent = function(cmd) {
74
+ this._cmd = cmd || this;
73
75
  if (cmd) {
74
76
  cmd._cmds.push(this);
77
+ if (this._name) {
78
+ this._cmd._cmdsByName[this._name] = this;
79
+ }
75
80
  }
76
- this._cmd = cmd || this;
77
81
  return this;
78
82
  };
79
83
 
@@ -221,6 +225,18 @@ exports.Cmd = Cmd = (function() {
221
225
  return this.cmd().name('completion').apply(require('./completion')).end();
222
226
  };
223
227
 
228
+ /**
229
+ Allow command to be extendable by external node.js modules.
230
+ @param {String} [pattern] Pattern of node.js module to find subcommands at.
231
+ @returns {COA.Cmd} this instance (for chainability)
232
+ */
233
+
234
+
235
+ Cmd.prototype.extendable = function(pattern) {
236
+ this._ext = pattern || true;
237
+ return this;
238
+ };
239
+
224
240
  Cmd.prototype._exit = function(msg, code) {
225
241
  return process.once('exit', function() {
226
242
  if (msg) {
@@ -304,7 +320,7 @@ exports.Cmd = Cmd = (function() {
304
320
  };
305
321
 
306
322
  Cmd.prototype._parseCmd = function(argv, unparsed) {
307
- var cmd, i, optSeen;
323
+ var c, cmd, cmdDesc, e, i, optSeen, pkg;
308
324
  if (unparsed == null) {
309
325
  unparsed = [];
310
326
  }
@@ -314,8 +330,46 @@ exports.Cmd = Cmd = (function() {
314
330
  if (!i.indexOf('-')) {
315
331
  optSeen = true;
316
332
  }
317
- if (!optSeen && /^\w[\w-_]*$/.test(i) && (cmd = this._cmdsByName[i])) {
318
- return cmd._parseCmd(argv, unparsed);
333
+ if (!optSeen && /^\w[\w-_]*$/.test(i)) {
334
+ cmd = this._cmdsByName[i];
335
+ if (!cmd && this._ext) {
336
+ if (typeof this._ext === 'string') {
337
+ if (~this._ext.indexOf('%s')) {
338
+ pkg = UTIL.format(this._ext, i);
339
+ } else {
340
+ pkg = this._ext + i;
341
+ }
342
+ } else if (this._ext === true) {
343
+ pkg = i;
344
+ c = this;
345
+ while (true) {
346
+ pkg = c._name + '-' + pkg;
347
+ if (c._cmd === c) {
348
+ break;
349
+ }
350
+ c = c._cmd;
351
+ }
352
+ }
353
+ try {
354
+ cmdDesc = require(pkg);
355
+ } catch (_error) {
356
+ e = _error;
357
+ }
358
+ if (cmdDesc) {
359
+ if (typeof cmdDesc === 'function') {
360
+ this.cmd().name(i).apply(cmdDesc).end();
361
+ } else if (typeof cmdDesc === 'object') {
362
+ this.cmd(cmdDesc);
363
+ cmdDesc.name(i);
364
+ } else {
365
+ throw new Error('Error: Unsupported command declaration type, ' + 'should be function or COA.Cmd() object');
366
+ }
367
+ cmd = this._cmdsByName[i];
368
+ }
369
+ }
370
+ if (cmd) {
371
+ return cmd._parseCmd(argv, unparsed);
372
+ }
319
373
  }
320
374
  unparsed.push(i);
321
375
  }
package/lib/color.js CHANGED
@@ -1,4 +1,4 @@
1
- // Generated by CoffeeScript 1.4.0
1
+ // Generated by CoffeeScript 1.6.3
2
2
  var colors;
3
3
 
4
4
  colors = {
package/lib/completion.js CHANGED
@@ -1,4 +1,4 @@
1
- // Generated by CoffeeScript 1.4.0
1
+ // Generated by CoffeeScript 1.6.3
2
2
  /**
3
3
  Most of the code adopted from the npm package shell completion code.
4
4
  See https://github.com/isaacs/npm/blob/master/lib/completion.js
@@ -21,7 +21,7 @@ module.exports = function() {
21
21
  e.errno = require('constants').ENOTSUP;
22
22
  return this.reject(e);
23
23
  }
24
- if (!(process.env.COMP_CWORD != null) || !(process.env.COMP_LINE != null) || !(process.env.COMP_POINT != null)) {
24
+ if ((process.env.COMP_CWORD == null) || (process.env.COMP_LINE == null) || (process.env.COMP_POINT == null)) {
25
25
  return dumpScript(this._cmd._name);
26
26
  }
27
27
  console.error('COMP_LINE: %s', process.env.COMP_LINE);
package/lib/index.js CHANGED
@@ -1,7 +1,10 @@
1
- // Generated by CoffeeScript 1.4.0
2
-
1
+ // Generated by CoffeeScript 1.6.3
3
2
  exports.Cmd = require('./cmd').Cmd;
4
3
 
4
+ exports.Opt = require('./cmd').Opt;
5
+
6
+ exports.Arg = require('./cmd').Arg;
7
+
5
8
  exports.shell = require('./shell');
6
9
 
7
10
  exports.require = require;
package/lib/opt.js CHANGED
@@ -1,4 +1,4 @@
1
- // Generated by CoffeeScript 1.4.0
1
+ // Generated by CoffeeScript 1.6.3
2
2
  var Cmd, Color, Opt, Q, fs;
3
3
 
4
4
  fs = require('fs');
package/lib/shell.js CHANGED
@@ -1,5 +1,4 @@
1
- // Generated by CoffeeScript 1.4.0
2
-
1
+ // Generated by CoffeeScript 1.6.3
3
2
  exports.unescape = function(w) {
4
3
  w = w.charAt(0) === '"' ? w.replace(/^"|([^\\])"$/g, '$1') : w.replace(/\\ /g, ' ');
5
4
  return w.replace(/\\("|'|\$|`|\\)/g, '$1');
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.3.9",
4
+ "version": "0.4.0",
5
5
  "homepage": "http://github.com/veged/coa",
6
6
  "author": "Sergey Berezhnoy <veged@ya.ru> (http://github.com/veged)",
7
7
  "maintainers": [
@@ -19,15 +19,15 @@
19
19
  "lib": "./lib"
20
20
  },
21
21
  "dependencies": {
22
- "q": "~0.8.10"
22
+ "q": "~0.9.6"
23
23
  },
24
24
  "devDependencies": {
25
- "coffee-script": "~1.4.0",
26
- "istanbul": "~0.1.11",
25
+ "coffee-script": "~1.6.3",
26
+ "istanbul": "~0.1.40",
27
27
  "mocha-as-promised": "*",
28
28
  "mocha-istanbul": "*",
29
- "mocha": "~1.6.0",
30
- "chai": "~1.3.0"
29
+ "mocha": "~1.12.0",
30
+ "chai": "~1.7.2"
31
31
  },
32
32
  "scripts": {
33
33
  "test": "make test",
package/src/cmd.coffee CHANGED
@@ -32,6 +32,8 @@ exports.Cmd = class Cmd
32
32
 
33
33
  @_args = []
34
34
 
35
+ @_ext = false
36
+
35
37
  @get: (propertyName, func) ->
36
38
  Object.defineProperty @::, propertyName,
37
39
  configurable: true
@@ -52,8 +54,10 @@ exports.Cmd = class Cmd
52
54
  @_api
53
55
 
54
56
  _parent: (cmd) ->
55
- if cmd then cmd._cmds.push @
56
57
  @_cmd = cmd or this
58
+ if cmd
59
+ cmd._cmds.push @
60
+ if @_name then @_cmd._cmdsByName[@_name] = @
57
61
  @
58
62
 
59
63
  ###*
@@ -163,6 +167,15 @@ exports.Cmd = class Cmd
163
167
  .apply(require './completion')
164
168
  .end()
165
169
 
170
+ ###*
171
+ Allow command to be extendable by external node.js modules.
172
+ @param {String} [pattern] Pattern of node.js module to find subcommands at.
173
+ @returns {COA.Cmd} this instance (for chainability)
174
+ ###
175
+ extendable: (pattern) ->
176
+ @_ext = pattern or true
177
+ @
178
+
166
179
  _exit: (msg, code) ->
167
180
  process.once 'exit', ->
168
181
  if msg then UTIL.error msg
@@ -233,8 +246,49 @@ exports.Cmd = class Cmd
233
246
  while i = argv.shift()
234
247
  if not i.indexOf '-'
235
248
  optSeen = true
236
- if not optSeen and /^\w[\w-_]*$/.test(i) and cmd = @_cmdsByName[i]
237
- return cmd._parseCmd argv, unparsed
249
+ if not optSeen and /^\w[\w-_]*$/.test(i)
250
+ cmd = @_cmdsByName[i]
251
+
252
+ if not cmd and @_ext
253
+ # construct package name to require
254
+ if typeof @_ext is 'string'
255
+ if ~@_ext.indexOf('%s')
256
+ # use formatted string
257
+ pkg = UTIL.format(@_ext, i)
258
+ else
259
+ # just append subcommand name to the prefix
260
+ pkg = @_ext + i
261
+ else if @_ext is true
262
+ # use default scheme: <command>-<subcommand>-<subcommand> and so on
263
+ pkg = i
264
+ c = @
265
+ loop
266
+ pkg = c._name + '-' + pkg
267
+ if c._cmd is c then break
268
+ c = c._cmd
269
+
270
+ try
271
+ cmdDesc = require(pkg)
272
+ catch e
273
+
274
+ if cmdDesc
275
+ if typeof cmdDesc == 'function'
276
+ # set create subcommand, set its name and apply imported function
277
+ @cmd()
278
+ .name(i)
279
+ .apply(cmdDesc)
280
+ .end()
281
+ else if typeof cmdDesc == 'object'
282
+ # register subcommand
283
+ @cmd(cmdDesc)
284
+ # set command name
285
+ cmdDesc.name(i)
286
+ else
287
+ throw new Error 'Error: Unsupported command declaration type, ' +
288
+ 'should be function or COA.Cmd() object'
289
+ cmd = @_cmdsByName[i]
290
+ if cmd
291
+ return cmd._parseCmd argv, unparsed
238
292
 
239
293
  unparsed.push i
240
294
 
package/src/index.coffee CHANGED
@@ -1,3 +1,5 @@
1
1
  exports.Cmd = require('./cmd').Cmd
2
+ exports.Opt = require('./cmd').Opt
3
+ exports.Arg = require('./cmd').Arg
2
4
  exports.shell = require('./shell')
3
5
  exports.require = require;
package/test/coa.js CHANGED
@@ -338,6 +338,22 @@ describe('Arg', function() {
338
338
 
339
339
  describe('Cmd', function() {
340
340
 
341
+ var doTest = function(o) {
342
+ assert.deepEqual(o, {
343
+ opts: { opt: 'value' },
344
+ args: {
345
+ arg1: 'value',
346
+ arg2: ['value 1', 'value 2']
347
+ }
348
+ });
349
+ },
350
+
351
+ invokeOpts = { opt: 'value' },
352
+ invokeArgs = {
353
+ arg1: 'value',
354
+ arg2: ['value 1', 'value 2']
355
+ };
356
+
341
357
  describe('Subcommand', function() {
342
358
 
343
359
  var cmd = COA.Cmd()
@@ -357,23 +373,7 @@ describe('Cmd', function() {
357
373
  .act(function(opts, args) {
358
374
  return { opts: opts, args: args };
359
375
  })
360
- .end(),
361
-
362
- doTest = function(o) {
363
- assert.deepEqual(o, {
364
- opts: { opt: 'value' },
365
- args: {
366
- arg1: 'value',
367
- arg2: ['value 1', 'value 2']
368
- }
369
- });
370
- },
371
-
372
- invokeOpts = { opt: 'value' },
373
- invokeArgs = {
374
- arg1: 'value',
375
- arg2: ['value 1', 'value 2']
376
- };
376
+ .end();
377
377
 
378
378
  describe('when specified on command line', function() {
379
379
 
@@ -413,6 +413,80 @@ describe('Cmd', function() {
413
413
 
414
414
  });
415
415
 
416
+ describe('External subcommand', function() {
417
+
418
+ describe('default scheme: cmd.extendable()', function() {
419
+
420
+ describe('when described as a function', function() {
421
+ var cmd = COA.Cmd()
422
+ .name('coa')
423
+ .extendable();
424
+
425
+ it('should be invoked and accept passed opts and args', function() {
426
+ return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
427
+ .then(doTest);
428
+ });
429
+ });
430
+
431
+ describe('when described as an COA.Cmd() object', function() {
432
+ var cmd = COA.Cmd()
433
+ .name('coa')
434
+ .extendable();
435
+
436
+ it('should be invoked and accept passed opts and args', function() {
437
+ return cmd.do(['test-obj', '--opt', 'value', 'value', 'value 1', 'value 2'])
438
+ .then(doTest);
439
+ });
440
+ });
441
+
442
+ describe('2nd level subcommand', function() {
443
+ var cmd = COA.Cmd()
444
+ .name('coa')
445
+ .cmd()
446
+ .name('test')
447
+ .extendable()
448
+ .end();
449
+
450
+ it('should be invoked and accept passed opts and args', function() {
451
+ return cmd.do(['test', 'obj', '--opt', 'value', 'value', 'value 1', 'value 2'])
452
+ .then(doTest);
453
+ });
454
+ });
455
+
456
+ });
457
+
458
+ describe("common prefix: cmd.extendable('coa-')", function() {
459
+
460
+ describe('when described as a function', function() {
461
+ var cmd = COA.Cmd()
462
+ .name('coa')
463
+ .extendable('coa-');
464
+
465
+ it('should be invoked and accept passed opts and args', function() {
466
+ return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
467
+ .then(doTest);
468
+ });
469
+ });
470
+
471
+ });
472
+
473
+ describe("format string: cmd.extendable('coa-%s')", function() {
474
+
475
+ describe('when described as a function', function() {
476
+ var cmd = COA.Cmd()
477
+ .name('coa')
478
+ .extendable('coa-%s');
479
+
480
+ it('should be invoked and accept passed opts and args', function() {
481
+ return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
482
+ .then(doTest);
483
+ });
484
+ });
485
+
486
+ });
487
+
488
+ });
489
+
416
490
  it('helpful(), name(), title()');
417
491
 
418
492
  });
package/test/mocha.opts CHANGED
@@ -1,4 +1,3 @@
1
1
  --reporter spec
2
- --ignore-leaks
3
2
  --timeout 0
4
3
  --require test/common.js
package/tests/api-h.js CHANGED
@@ -6,4 +6,4 @@ require('..').Cmd()
6
6
  .then(function(res) {
7
7
  console.log(res);
8
8
  })
9
- .end(); // Q.end()
9
+ .done(); // Q.done()