coa 0.3.9 → 0.4.0

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/.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()