yargs 3.11.0 → 3.15.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/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  ## Change Log
2
2
 
3
+ ### v3.15.0 (2015/07/06 06:01 +00:00)
4
+ - [#197](https://github.com/bcoe/yargs/pull/197) tweaks to how errors bubble up from parser.js (@bcoe)
5
+ - [#193](https://github.com/bcoe/yargs/pull/193) upgraded nyc, reporting now happens by default (@bcoe)
6
+
7
+ ### v3.14.0 (2015/06/28 02:12 +00:00)
8
+
9
+ - [#192](https://github.com/bcoe/yargs/pull/192) standard style nits (@bcoe)
10
+ - [#190](https://github.com/bcoe/yargs/pull/190) allow for hidden commands, e.g.,
11
+ .completion('completion', false) (@tschaub)
12
+
13
+ ### v3.13.0 (2015/06/24 04:12 +00:00)
14
+
15
+ - [#187](https://github.com/bcoe/yargs/pull/187) completion now behaves differently
16
+ if it is being run in the context of a command (@tschaub)
17
+ - [#186](https://github.com/bcoe/yargs/pull/186) if no matches are found for a completion
18
+ default to filename completion (@tschaub)
19
+
20
+ ### v3.12.0 (2015/06/19 03:23 +00:00)
21
+ - [#183](https://github.com/bcoe/yargs/pull/183) don't complete commands if they've already been completed (@tschaub)
22
+ - [#181](https://github.com/bcoe/yargs/pull/181) various fixes for completion. (@bcoe, @tschaub)
23
+ - [#182](https://github.com/bcoe/yargs/pull/182) you can now set a maximum # of of required arguments (@bcoe)
24
+
3
25
  ### v3.11.0 (2015/06/15 05:15 +00:00)
4
26
 
5
27
  - [#173](https://github.com/bcoe/yargs/pull/173) update standard, window-size, chai (@bcoe)
package/README.md CHANGED
@@ -398,17 +398,20 @@ displaying the value in the usage instructions:
398
398
  ```
399
399
 
400
400
  .demand(key, [msg | boolean])
401
- -----------------------------
401
+ ------------------------------
402
402
  .require(key, [msg | boolean])
403
403
  ------------------------------
404
404
  .required(key, [msg | boolean])
405
- -------------------------------
405
+ ------------------------------
406
+ .demand(count, [max], [msg])
407
+ ------------------------------
406
408
 
407
409
  If `key` is a string, show the usage information and exit if `key` wasn't
408
410
  specified in `process.argv`.
409
411
 
410
412
  If `key` is a number, demand at least as many non-option arguments, which show
411
- up in `argv._`.
413
+ up in `argv._`. A second number can also optionally be provided, which indicates
414
+ the maximum number of non-option arguments.
412
415
 
413
416
  If `key` is an Array, demand each element.
414
417
 
@@ -506,8 +509,10 @@ present script similar to how `$0` works in bash or perl.
506
509
 
507
510
  Document the commands exposed by your application.
508
511
 
509
- use `desc` to provide a description for each command your application accepts (the
510
- values stored in `argv._`).
512
+ Use `desc` to provide a description for each command your application accepts (the
513
+ values stored in `argv._`). Set `desc` to `false` to create a hidden command.
514
+ Hidden commands don't show up in the help output and aren't available for
515
+ completion.
511
516
 
512
517
  Optionally, you can provide a handler `fn` which will be executed when
513
518
  a given command is provided. The handler will be executed with an instance
package/completion.sh.hbs CHANGED
@@ -16,6 +16,12 @@ _yargs_completions()
16
16
  type_list=`{{app_path}} --get-yargs-completions $args`
17
17
 
18
18
  COMPREPLY=( $(compgen -W "${type_list}" -- ${cur_word}) )
19
+
20
+ # if no match was found, fall back to filename completion
21
+ if [ ${#COMPREPLY[@]} -eq 0 ]; then
22
+ COMPREPLY=( $(compgen -f -- "${cur_word}" ) )
23
+ fi
24
+
19
25
  return 0
20
26
  }
21
27
  complete -F _yargs_completions {{app_name}}
package/index.js CHANGED
@@ -66,7 +66,6 @@ function Argv (processArgs, cwd) {
66
66
  strict = false
67
67
  helpOpt = null
68
68
  versionOpt = null
69
- completionOpt = null
70
69
  commandHandlers = {}
71
70
  self.parsed = false
72
71
 
@@ -112,7 +111,9 @@ function Argv (processArgs, cwd) {
112
111
  }
113
112
 
114
113
  self.command = function (cmd, description, fn) {
115
- usage.command(cmd, description)
114
+ if (description !== false) {
115
+ usage.command(cmd, description)
116
+ }
116
117
  if (fn) commandHandlers[cmd] = fn
117
118
  return self
118
119
  }
@@ -160,10 +161,18 @@ function Argv (processArgs, cwd) {
160
161
  }
161
162
 
162
163
  var demanded = {}
163
- self.demand = self.required = self.require = function (keys, msg) {
164
+ self.demand = self.required = self.require = function (keys, max, msg) {
165
+ // you can optionally provide a 'max' key,
166
+ // which will raise an exception if too many '_'
167
+ // options are provided.
168
+ if (typeof max !== 'number') {
169
+ msg = max
170
+ max = Infinity
171
+ }
172
+
164
173
  if (typeof keys === 'number') {
165
- if (!demanded._) demanded._ = { count: 0, msg: null }
166
- demanded._.count += keys
174
+ if (!demanded._) demanded._ = { count: 0, msg: null, max: max }
175
+ demanded._.count = keys
167
176
  demanded._.msg = msg
168
177
  } else if (Array.isArray(keys)) {
169
178
  keys.forEach(function (key) {
@@ -344,7 +353,6 @@ function Argv (processArgs, cwd) {
344
353
  return usage.help()
345
354
  }
346
355
 
347
- var completionOpt = null
348
356
  var completionCommand = null
349
357
  self.completion = function (cmd, desc, fn) {
350
358
  // a function to execute when generating
@@ -356,9 +364,11 @@ function Argv (processArgs, cwd) {
356
364
  }
357
365
 
358
366
  // register the completion command.
359
- completionCommand = cmd
360
- completionOpt = completion.completionKey
361
- self.command(completionCommand, desc || 'generate bash completion script')
367
+ completionCommand = cmd || 'completion'
368
+ if (!desc && desc !== false) {
369
+ desc = 'generate bash completion script'
370
+ }
371
+ self.command(completionCommand, desc)
362
372
 
363
373
  // a function can be provided
364
374
  if (fn) completion.registerFunction(fn)
@@ -408,12 +418,13 @@ function Argv (processArgs, cwd) {
408
418
 
409
419
  self.parsed = parsed
410
420
 
411
- // generate a completion script for adding to ~/.bashrc.
412
- if (completionCommand && ~argv._.indexOf(completionCommand)) {
413
- self.showCompletionScript()
414
- if (exitProcess) {
415
- process.exit(0)
416
- }
421
+ // while building up the argv object, there
422
+ // are two passes through the parser. If completion
423
+ // is being performed short-circuit on the first pass.
424
+ if (completionCommand &&
425
+ (process.argv.join(' ')).indexOf(completion.completionKey) !== -1 &&
426
+ !argv[completion.completionKey]) {
427
+ return argv
417
428
  }
418
429
 
419
430
  // if there's a handler associated with a
@@ -426,6 +437,31 @@ function Argv (processArgs, cwd) {
426
437
  }
427
438
  }
428
439
 
440
+ // generate a completion script for adding to ~/.bashrc.
441
+ if (completionCommand && ~argv._.indexOf(completionCommand) && !argv[completion.completionKey]) {
442
+ self.showCompletionScript()
443
+ if (exitProcess) {
444
+ process.exit(0)
445
+ }
446
+ }
447
+
448
+ // we must run completions first, a user might
449
+ // want to complete the --help or --version option.
450
+ if (completion.completionKey in argv) {
451
+ // we allow for asynchronous completions,
452
+ // e.g., loading in a list of commands from an API.
453
+ completion.getCompletion(function (completions) {
454
+ ;(completions || []).forEach(function (completion) {
455
+ console.log(completion)
456
+ })
457
+
458
+ if (exitProcess) {
459
+ process.exit(0)
460
+ }
461
+ })
462
+ return
463
+ }
464
+
429
465
  Object.keys(argv).forEach(function (key) {
430
466
  if (key === helpOpt && argv[key]) {
431
467
  self.showHelp('log')
@@ -437,32 +473,22 @@ function Argv (processArgs, cwd) {
437
473
  if (exitProcess) {
438
474
  process.exit(0)
439
475
  }
440
- } else if (key === completionOpt) {
441
- // we allow for asynchronous completions,
442
- // e.g., loading in a list of commands from an API.
443
- completion.getCompletion(function (completions) {
444
- ;(completions || []).forEach(function (completion) {
445
- console.log(completion)
446
- })
447
-
448
- if (exitProcess) {
449
- process.exit(0)
450
- }
451
- })
452
- return
453
476
  }
454
477
  })
455
478
 
456
- validation.nonOptionCount(argv)
457
- validation.missingArgumentValue(argv)
458
- validation.requiredArguments(argv)
459
-
460
- if (strict) {
461
- validation.unknownArguments(argv, aliases)
479
+ if (parsed.error) throw parsed.error
480
+
481
+ // if we're executed via bash completion, don't
482
+ // bother with validation.
483
+ if (!argv[completion.completionKey]) {
484
+ validation.nonOptionCount(argv)
485
+ validation.missingArgumentValue(argv)
486
+ validation.requiredArguments(argv)
487
+ if (strict) validation.unknownArguments(argv, aliases)
488
+ validation.customChecks(argv, aliases)
489
+ validation.implications(argv)
462
490
  }
463
491
 
464
- validation.customChecks(argv, aliases)
465
- validation.implications(argv)
466
492
  setPlaceholderKeys(argv)
467
493
 
468
494
  return argv
package/lib/completion.js CHANGED
@@ -29,9 +29,18 @@ module.exports = function (yargs, usage) {
29
29
  }
30
30
  }
31
31
 
32
+ var handlers = yargs.getCommandHandlers()
33
+ for (var i = 0, ii = previous.length; i < ii; ++i) {
34
+ if (handlers[previous[i]]) {
35
+ return handlers[previous[i]](yargs.reset())
36
+ }
37
+ }
38
+
32
39
  if (!current.match(/^-/)) {
33
40
  usage.getCommands().forEach(function (command) {
34
- completions.push(command[0])
41
+ if (previous.indexOf(command[0]) === -1) {
42
+ completions.push(command[0])
43
+ }
35
44
  })
36
45
  }
37
46
 
package/lib/parser.js CHANGED
@@ -9,6 +9,8 @@ function increment (orig) {
9
9
 
10
10
  module.exports = function (args, opts) {
11
11
  if (!opts) opts = {}
12
+
13
+ var error = null
12
14
  var flags = { arrays: {}, bools: {}, strings: {}, counts: {}, normalize: {}, configs: {} }
13
15
 
14
16
  ;[].concat(opts['array']).filter(Boolean).forEach(function (key) {
@@ -64,13 +66,13 @@ module.exports = function (args, opts) {
64
66
  }
65
67
 
66
68
  for (var i = 0; i < args.length; i++) {
67
- var arg = args[i],
68
- broken,
69
- key,
70
- letters,
71
- m,
72
- next,
73
- value
69
+ var arg = args[i]
70
+ var broken
71
+ var key
72
+ var letters
73
+ var m
74
+ var next
75
+ var value
74
76
 
75
77
  // -- seperated by =
76
78
  if (arg.match(/^--.+=/)) {
@@ -232,7 +234,7 @@ module.exports = function (args, opts) {
232
234
  function eatNargs (i, key, args) {
233
235
  var toEat = checkAllAliases(key, opts.narg)
234
236
 
235
- if (args.length - (i + 1) < toEat) throw Error('not enough arguments following: ' + key)
237
+ if (args.length - (i + 1) < toEat) error = Error('not enough arguments following: ' + key)
236
238
 
237
239
  for (var ii = i + 1; ii < (toEat + i + 1); ii++) {
238
240
  setArg(key, args[ii])
@@ -331,7 +333,7 @@ module.exports = function (args, opts) {
331
333
  }
332
334
  })
333
335
  } catch (ex) {
334
- throw Error('invalid json config file: ' + configPath)
336
+ if (argv[configKey]) error = Error('invalid json config file: ' + configPath)
335
337
  }
336
338
  }
337
339
  })
@@ -443,6 +445,7 @@ module.exports = function (args, opts) {
443
445
  return {
444
446
  argv: argv,
445
447
  aliases: aliases,
448
+ error: error,
446
449
  newAliases: newAliases
447
450
  }
448
451
  }
package/lib/validation.js CHANGED
@@ -7,14 +7,19 @@ module.exports = function (yargs, usage) {
7
7
  // arguments were provided, i.e., '_'.
8
8
  self.nonOptionCount = function (argv) {
9
9
  var demanded = yargs.getDemanded()
10
+ var _s = argv._.length
10
11
 
11
- if (demanded._ && argv._.length < demanded._.count) {
12
+ if (demanded._ && (_s < demanded._.count || _s > demanded._.max)) {
12
13
  if (demanded._.msg !== undefined) {
13
14
  usage.fail(demanded._.msg)
14
- } else {
15
+ } else if (_s < demanded._.count) {
15
16
  usage.fail('Not enough non-option arguments: got ' +
16
17
  argv._.length + ', need at least ' + demanded._.count
17
18
  )
19
+ } else {
20
+ usage.fail('Too many non-option arguments: got ' +
21
+ argv._.length + ', maximum of ' + demanded._.max
22
+ )
18
23
  }
19
24
  }
20
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yargs",
3
- "version": "3.11.0",
3
+ "version": "3.15.0",
4
4
  "description": "Light-weight option parsing with an argv hash. No optstrings attached.",
5
5
  "main": "./index.js",
6
6
  "files": [
@@ -20,11 +20,11 @@
20
20
  "coveralls": "^2.11.2",
21
21
  "hashish": "0.0.4",
22
22
  "mocha": "^2.2.1",
23
- "nyc": "^2.2.1",
24
- "standard": "^4.2.1"
23
+ "nyc": "^3.0.0",
24
+ "standard": "^4.4.0"
25
25
  },
26
26
  "scripts": {
27
- "test": "standard && nyc mocha --check-leaks && nyc report",
27
+ "test": "standard && nyc mocha --check-leaks",
28
28
  "coverage": "nyc report --reporter=text-lcov | coveralls"
29
29
  },
30
30
  "repository": {
@@ -76,6 +76,10 @@
76
76
  {
77
77
  "name": "Lin Clark",
78
78
  "url": "https://github.com/linclark"
79
+ },
80
+ {
81
+ "name": "Tim Schaub",
82
+ "url": "https://github.com/tschaub"
79
83
  }
80
84
  ],
81
85
  "license": "MIT",