yargs 4.6.0-candidate → 4.7.1

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
@@ -2,6 +2,34 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ <a name="4.7.1"></a>
6
+ ## [4.7.1](https://github.com/yargs/yargs/compare/v4.7.0...v4.7.1) (2016-05-15)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * switch to using `const` rather than `var` ([#499](https://github.com/yargs/yargs/pull/499))
12
+ * make stdout flush on newer versions of Node.js ([#501](https://github.com/yargs/yargs/issues/501)) ([9f8c6f4](https://github.com/yargs/yargs/commit/9f8c6f4))
13
+
14
+
15
+
16
+ <a name="4.7.0"></a>
17
+ # [4.7.0](https://github.com/yargs/yargs/compare/v4.6.0...v4.7.0) (2016-05-02)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **pkgConf:** fix aliases issues in .pkgConf() ([#478](https://github.com/yargs/yargs/issues/478))([b900502](https://github.com/yargs/yargs/commit/b900502))
23
+
24
+
25
+ ### Features
26
+
27
+ * **completion:** allow to get completions for any string, not just process.argv ([#470](https://github.com/yargs/yargs/issues/470))([74fcfbc](https://github.com/yargs/yargs/commit/74fcfbc))
28
+ * **configuration:** Allow to directly pass a configuration object to .config() ([#480](https://github.com/yargs/yargs/issues/480))([e0a7e05](https://github.com/yargs/yargs/commit/e0a7e05))
29
+ * **validation:** Add .skipValidation() method ([#471](https://github.com/yargs/yargs/issues/471))([d72badb](https://github.com/yargs/yargs/commit/d72badb))
30
+
31
+
32
+
5
33
  <a name="4.6.0"></a>
6
34
  # [4.6.0](https://github.com/yargs/yargs/compare/v4.5.0...v4.6.0) (2016-04-11)
7
35
 
package/README.md CHANGED
@@ -29,8 +29,7 @@ var argv = require('yargs').argv;
29
29
 
30
30
  if (argv.ships > 3 && argv.distance < 53.5) {
31
31
  console.log('Plunder more riffiwobbles!');
32
- }
33
- else {
32
+ } else {
34
33
  console.log('Retreat from the xupptumblers!');
35
34
  }
36
35
  ````
@@ -651,7 +650,9 @@ var argv = require('yargs')
651
650
  ```
652
651
 
653
652
  <a name="config"></a>.config([key], [description], [parseFn])
654
- ------------
653
+ -------------------------------------------------------------
654
+ .config(object)
655
+ ---------------
655
656
 
656
657
  Tells the parser that if the option specified by `key` is passed in, it
657
658
  should be interpreted as a path to a JSON config file. The file is loaded
@@ -674,6 +675,24 @@ var argv = require('yargs')
674
675
  .argv
675
676
  ```
676
677
 
678
+ You can also pass an explicit configuration `object`, it will be parsed
679
+ and its properties will be set as arguments.
680
+
681
+ ```js
682
+ var argv = require('yargs')
683
+ .config({foo: 1, bar: 2})
684
+ .argv
685
+ console.log(argv)
686
+ ```
687
+
688
+ ```
689
+ $ node test.js
690
+ { _: [],
691
+ foo: 1,
692
+ bar: 2,
693
+ '$0': 'test.js' }
694
+ ```
695
+
677
696
  <a name="count"></a>.count(key)
678
697
  ------------
679
698
 
@@ -681,7 +700,12 @@ Interpret `key` as a boolean flag, but set its parsed value to the number of
681
700
  flag occurrences rather than `true` or `false`. Default value is thus `0`.
682
701
 
683
702
  <a name="default"></a>.default(key, value, [description])
684
- --------------------
703
+ ---------------------------------------------------------
704
+ .defaults(key, value, [description])
705
+ ------------------------------------
706
+
707
+ **Note:** The `.defaults()` alias is deprecated. It will be
708
+ removed in the next major version.
685
709
 
686
710
  Set `argv[key]` to `value` if no option was specified in `process.argv`.
687
711
 
@@ -762,6 +786,9 @@ Should yargs attempt to detect the os' locale? Defaults to `true`.
762
786
  Tell yargs to parse environment variables matching the given prefix and apply
763
787
  them to argv as though they were command line arguments.
764
788
 
789
+ Use the "__" separator in the environment variable to indicate nested options.
790
+ (e.g. prefix_nested__foo => nested.foo)
791
+
765
792
  If this method is called with no argument or with an empty string or with `true`,
766
793
  then all env vars will be applied to argv.
767
794
 
@@ -860,6 +887,29 @@ var argv = require('yargs')
860
887
  .argv
861
888
  ```
862
889
 
890
+ .getCompletion(args, done);
891
+ ---------------------------
892
+
893
+ Allows to programmatically get completion choices for any line.
894
+
895
+ `args`: An array of the words in the command line to complete.
896
+
897
+ `done`: The callback to be called with the resulting completions.
898
+
899
+ For example:
900
+
901
+ ```js
902
+ require('yargs')
903
+ .option('foobar', {})
904
+ .option('foobaz', {})
905
+ .completion()
906
+ .getCompletion(['./test.js', '--foo'], function (completions) {
907
+ console.log(completions)
908
+ })
909
+ ```
910
+
911
+ Outputs the same completion choices as `./test.js --foo`<kbd>TAB</kbd>: `--foobar` and `--foobaz`
912
+
863
913
  <a name="global"></a>.global(globals)
864
914
  ------------
865
915
 
@@ -1134,6 +1184,7 @@ Valid `opt` keys include:
1134
1184
  - `normalize`: boolean, apply `path.normalize()` to the option, see [`normalize()`](#normalize)
1135
1185
  - `number`: boolean, interpret option as a number, [`number()`](#number)
1136
1186
  - `requiresArg`: boolean, require the option be specified with a value, see [`requiresArg()`](#requiresArg)
1187
+ - `skipValidation`: boolean, skips validation if the option is present, see [`skipValidation()`](#skipValidation)
1137
1188
  - `string`: boolean, interpret option as a string, see [`string()`](#string)
1138
1189
  - `type`: one of the following strings
1139
1190
  - `'array'`: synonymous for `array: true`, see [`array()`](#array)
@@ -1152,8 +1203,8 @@ Parse `args` instead of `process.argv`. Returns the `argv` object.
1152
1203
  .pkgConf(key, [cwd])
1153
1204
  ------------
1154
1205
 
1155
- Similar to [`config()`](#config), indicates that yargs should read
1156
- default argument values from the specified key in package.json.
1206
+ Similar to [`config()`](#config), indicates that yargs should interpret the object from the specified key in package.json
1207
+ as a configuration object.
1157
1208
 
1158
1209
  `cwd` can optionally be provided, the package.json will be read
1159
1210
  from this location.
@@ -1274,6 +1325,12 @@ Missing argument value: f
1274
1325
  Specify --help for available options
1275
1326
  ```
1276
1327
 
1328
+ <a name="skipValidation"></a>.skipValidation(key)
1329
+ -----------------
1330
+
1331
+ Specifies either a single option key (string), or an array of options.
1332
+ If any of the options is present, yargs validation is skipped.
1333
+
1277
1334
  .strict()
1278
1335
  ---------
1279
1336
 
package/index.js CHANGED
@@ -1,14 +1,14 @@
1
1
  // classic singleton yargs API, to use yargs
2
2
  // without running as a singleton do:
3
3
  // require('yargs/yargs')(process.argv.slice(2))
4
- var yargs = require('./yargs')
4
+ const yargs = require('./yargs')
5
5
 
6
6
  Argv(process.argv.slice(2))
7
7
 
8
8
  module.exports = Argv
9
9
 
10
10
  function Argv (processArgs, cwd) {
11
- var argv = yargs(processArgs, cwd, require)
11
+ const argv = yargs(processArgs, cwd, require)
12
12
  singletonify(argv)
13
13
  return argv
14
14
  }
package/lib/command.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // and populating argv with said positional
3
3
  // arguments.
4
4
  module.exports = function (yargs, usage, validation) {
5
- var self = {}
5
+ const self = {}
6
6
 
7
7
  var handlers = {}
8
8
  self.addHandler = function (cmd, description, builder, handler) {
package/lib/completion.js CHANGED
@@ -1,20 +1,20 @@
1
- var fs = require('fs')
2
- var path = require('path')
1
+ const fs = require('fs')
2
+ const path = require('path')
3
3
 
4
4
  // add bash completions to your
5
5
  // yargs-powered applications.
6
6
  module.exports = function (yargs, usage, command) {
7
- var self = {
7
+ const self = {
8
8
  completionKey: 'get-yargs-completions'
9
9
  }
10
10
 
11
11
  // get a list of completion commands.
12
- self.getCompletion = function (done) {
13
- var completions = []
14
- var current = process.argv[process.argv.length - 1]
15
- var previous = process.argv.slice(process.argv.indexOf('--' + self.completionKey) + 1)
16
- var argv = yargs.parse(previous)
17
- var aliases = yargs.parsed.aliases
12
+ // 'args' is the array of strings from the line to be completed
13
+ self.getCompletion = function (args, done) {
14
+ const completions = []
15
+ const current = args.length ? args[args.length - 1] : ''
16
+ const argv = yargs.parse(args, true)
17
+ const aliases = yargs.parsed.aliases
18
18
 
19
19
  // a custom completion function can be provided
20
20
  // to completion().
@@ -42,15 +42,15 @@ module.exports = function (yargs, usage, command) {
42
42
  }
43
43
 
44
44
  var handlers = command.getCommandHandlers()
45
- for (var i = 0, ii = previous.length; i < ii; ++i) {
46
- if (handlers[previous[i]] && handlers[previous[i]].builder) {
47
- return handlers[previous[i]].builder(yargs.reset()).argv
45
+ for (var i = 0, ii = args.length; i < ii; ++i) {
46
+ if (handlers[args[i]] && handlers[args[i]].builder) {
47
+ return handlers[args[i]].builder(yargs.reset()).argv
48
48
  }
49
49
  }
50
50
 
51
51
  if (!current.match(/^-/)) {
52
52
  usage.getCommands().forEach(function (command) {
53
- if (previous.indexOf(command[0]) === -1) {
53
+ if (args.indexOf(command[0]) === -1) {
54
54
  completions.push(command[0])
55
55
  }
56
56
  })
@@ -58,12 +58,12 @@ module.exports = function (yargs, usage, command) {
58
58
 
59
59
  if (current.match(/^-/)) {
60
60
  Object.keys(yargs.getOptions().key).forEach(function (key) {
61
- // If the key and its aliases aren't in 'previous', add the key to 'completions'
61
+ // If the key and its aliases aren't in 'args', add the key to 'completions'
62
62
  var keyAndAliases = [key].concat(aliases[key] || [])
63
- var notInPrevious = keyAndAliases.every(function (val) {
64
- return previous.indexOf('--' + val) === -1
63
+ var notInArgs = keyAndAliases.every(function (val) {
64
+ return args.indexOf('--' + val) === -1
65
65
  })
66
- if (notInPrevious) {
66
+ if (notInArgs) {
67
67
  completions.push('--' + key)
68
68
  }
69
69
  })
package/lib/obj-filter.js CHANGED
@@ -1,5 +1,5 @@
1
1
  module.exports = function (original, filter) {
2
- var obj = {}
2
+ const obj = {}
3
3
  filter = filter || function (k, v) { return true }
4
4
  Object.keys(original || {}).forEach(function (key) {
5
5
  if (filter(key, original[key])) {
package/lib/usage.js CHANGED
@@ -1,14 +1,15 @@
1
1
  // this file handles outputting usage instructions,
2
2
  // failures, etc. keeps logging in one place.
3
- var cliui = require('cliui')
4
- var decamelize = require('decamelize')
5
- var stringWidth = require('string-width')
6
- var wsize = require('window-size')
7
- var objFilter = require('./obj-filter')
3
+ const cliui = require('cliui')
4
+ const decamelize = require('decamelize')
5
+ const stringWidth = require('string-width')
6
+ const wsize = require('window-size')
7
+ const objFilter = require('./obj-filter')
8
+ const setBlocking = require('set-blocking')
8
9
 
9
10
  module.exports = function (yargs, y18n) {
10
- var __ = y18n.__
11
- var self = {}
11
+ const __ = y18n.__
12
+ const self = {}
12
13
 
13
14
  // methods for ouputting/building failure message.
14
15
  var fails = []
@@ -37,6 +38,8 @@ module.exports = function (yargs, y18n) {
37
38
  f(msg, err)
38
39
  })
39
40
  } else {
41
+ if (yargs.getExitProcess()) setBlocking(true)
42
+
40
43
  // don't output failure message more than once
41
44
  if (!failureOutput) {
42
45
  failureOutput = true
package/lib/validation.js CHANGED
@@ -1,17 +1,17 @@
1
- var objFilter = require('./obj-filter')
1
+ const objFilter = require('./obj-filter')
2
2
 
3
3
  // validation-type-stuff, missing params,
4
4
  // bad implications, custom checks.
5
5
  module.exports = function (yargs, usage, y18n) {
6
- var __ = y18n.__
7
- var __n = y18n.__n
8
- var self = {}
6
+ const __ = y18n.__
7
+ const __n = y18n.__n
8
+ const self = {}
9
9
 
10
10
  // validate appropriate # of non-option
11
11
  // arguments were provided, i.e., '_'.
12
12
  self.nonOptionCount = function (argv) {
13
- var demanded = yargs.getDemanded()
14
- var _s = argv._.length
13
+ const demanded = yargs.getDemanded()
14
+ const _s = argv._.length
15
15
 
16
16
  if (demanded._ && (_s < demanded._.count || _s > demanded._.max)) {
17
17
  if (demanded._.msg !== undefined) {
@@ -41,14 +41,14 @@ module.exports = function (yargs, usage, y18n) {
41
41
  // make sure that any args that require an
42
42
  // value (--foo=bar), have a value.
43
43
  self.missingArgumentValue = function (argv) {
44
- var defaultValues = [true, false, '']
45
- var options = yargs.getOptions()
44
+ const defaultValues = [true, false, '']
45
+ const options = yargs.getOptions()
46
46
 
47
47
  if (options.requiresArg.length > 0) {
48
- var missingRequiredArgs = []
48
+ const missingRequiredArgs = []
49
49
 
50
50
  options.requiresArg.forEach(function (key) {
51
- var value = argv[key]
51
+ const value = argv[key]
52
52
 
53
53
  // if a value is explicitly requested,
54
54
  // flag argument as missing if it does not
@@ -72,7 +72,7 @@ module.exports = function (yargs, usage, y18n) {
72
72
 
73
73
  // make sure all the required arguments are present.
74
74
  self.requiredArguments = function (argv) {
75
- var demanded = yargs.getDemanded()
75
+ const demanded = yargs.getDemanded()
76
76
  var missing = null
77
77
 
78
78
  Object.keys(demanded).forEach(function (key) {
@@ -83,15 +83,15 @@ module.exports = function (yargs, usage, y18n) {
83
83
  })
84
84
 
85
85
  if (missing) {
86
- var customMsgs = []
86
+ const customMsgs = []
87
87
  Object.keys(missing).forEach(function (key) {
88
- var msg = missing[key].msg
88
+ const msg = missing[key].msg
89
89
  if (msg && customMsgs.indexOf(msg) < 0) {
90
90
  customMsgs.push(msg)
91
91
  }
92
92
  })
93
93
 
94
- var customMsg = customMsgs.length ? '\n' + customMsgs.join('\n') : ''
94
+ const customMsg = customMsgs.length ? '\n' + customMsgs.join('\n') : ''
95
95
 
96
96
  usage.fail(__n(
97
97
  'Missing required argument: %s',
@@ -104,12 +104,12 @@ module.exports = function (yargs, usage, y18n) {
104
104
 
105
105
  // check for unknown arguments (strict-mode).
106
106
  self.unknownArguments = function (argv, aliases) {
107
- var aliasLookup = {}
108
- var descriptions = usage.getDescriptions()
109
- var demanded = yargs.getDemanded()
110
- var commandKeys = yargs.getCommandInstance().getCommands()
111
- var unknown = []
112
- var currentContext = yargs.getContext()
107
+ const aliasLookup = {}
108
+ const descriptions = usage.getDescriptions()
109
+ const demanded = yargs.getDemanded()
110
+ const commandKeys = yargs.getCommandInstance().getCommands()
111
+ const unknown = []
112
+ const currentContext = yargs.getContext()
113
113
 
114
114
  Object.keys(aliases).forEach(function (key) {
115
115
  aliases[key].forEach(function (alias) {
@@ -146,8 +146,8 @@ module.exports = function (yargs, usage, y18n) {
146
146
 
147
147
  // validate arguments limited to enumerated choices
148
148
  self.limitedChoices = function (argv) {
149
- var options = yargs.getOptions()
150
- var invalid = {}
149
+ const options = yargs.getOptions()
150
+ const invalid = {}
151
151
 
152
152
  if (!Object.keys(options.choices).length) return
153
153
 
@@ -163,7 +163,7 @@ module.exports = function (yargs, usage, y18n) {
163
163
  }
164
164
  })
165
165
 
166
- var invalidKeys = Object.keys(invalid)
166
+ const invalidKeys = Object.keys(invalid)
167
167
 
168
168
  if (!invalidKeys.length) return
169
169
 
@@ -188,7 +188,7 @@ module.exports = function (yargs, usage, y18n) {
188
188
  self.customChecks = function (argv, aliases) {
189
189
  checks.forEach(function (f) {
190
190
  try {
191
- var result = f(argv, aliases)
191
+ const result = f(argv, aliases)
192
192
  if (!result) {
193
193
  usage.fail(__('Argument check failed: %s', f.toString()))
194
194
  } else if (typeof result === 'string') {
@@ -216,11 +216,11 @@ module.exports = function (yargs, usage, y18n) {
216
216
  }
217
217
 
218
218
  self.implications = function (argv) {
219
- var implyFail = []
219
+ const implyFail = []
220
220
 
221
221
  Object.keys(implied).forEach(function (key) {
222
222
  var num
223
- var origKey = key
223
+ const origKey = key
224
224
  var value = implied[key]
225
225
 
226
226
  // convert string '1' to number 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yargs",
3
- "version": "4.6.0-candidate",
3
+ "version": "4.7.1",
4
4
  "description": "yargs the modern, pirate-themed, successor to optimist.",
5
5
  "main": "./index.js",
6
6
  "files": [
@@ -12,7 +12,7 @@
12
12
  "LICENSE"
13
13
  ],
14
14
  "dependencies": {
15
- "camelcase": "^2.0.1",
15
+ "camelcase": "^3.0.0",
16
16
  "cliui": "^3.2.0",
17
17
  "decamelize": "^1.1.1",
18
18
  "lodash.assign": "^4.0.3",
@@ -20,6 +20,7 @@
20
20
  "pkg-conf": "^1.1.2",
21
21
  "read-pkg-up": "^1.0.1",
22
22
  "require-main-filename": "^1.0.1",
23
+ "set-blocking": "^1.0.0",
23
24
  "string-width": "^1.0.1",
24
25
  "window-size": "^0.2.0",
25
26
  "y18n": "^3.2.1",
@@ -34,15 +35,15 @@
34
35
  "es6-promise": "^3.0.2",
35
36
  "hashish": "0.0.4",
36
37
  "mocha": "^2.4.5",
37
- "nyc": "^6.1.1",
38
+ "nyc": "^6.4.2",
38
39
  "rimraf": "^2.5.0",
39
- "standard": "^6.0.5",
40
- "standard-version": "^2.1.2",
40
+ "standard": "^7.0.0",
41
+ "standard-version": "^2.2.1",
41
42
  "which": "^1.1.2"
42
43
  },
43
44
  "scripts": {
44
45
  "pretest": "standard",
45
- "test": "nyc --cache mocha --require ./test/before.js --timeout=4000 --check-leaks",
46
+ "test": "nyc --cache mocha --require ./test/before.js --timeout=8000 --check-leaks",
46
47
  "coverage": "nyc report --reporter=text-lcov | coveralls",
47
48
  "version": "standard-version"
48
49
  },
@@ -69,4 +70,4 @@
69
70
  "engine": {
70
71
  "node": ">=0.10"
71
72
  }
72
- }
73
+ }
package/yargs.js CHANGED
@@ -1,29 +1,30 @@
1
- var assert = require('assert')
2
- var assign = require('lodash.assign')
3
- var Command = require('./lib/command')
4
- var Completion = require('./lib/completion')
5
- var Parser = require('yargs-parser')
6
- var path = require('path')
7
- var Usage = require('./lib/usage')
8
- var Validation = require('./lib/validation')
9
- var Y18n = require('y18n')
10
- var readPkgUp = require('read-pkg-up')
11
- var pkgConf = require('pkg-conf')
12
- var requireMainFilename = require('require-main-filename')
13
- var objFilter = require('./lib/obj-filter')
1
+ const assert = require('assert')
2
+ const assign = require('lodash.assign')
3
+ const Command = require('./lib/command')
4
+ const Completion = require('./lib/completion')
5
+ const Parser = require('yargs-parser')
6
+ const path = require('path')
7
+ const Usage = require('./lib/usage')
8
+ const Validation = require('./lib/validation')
9
+ const Y18n = require('y18n')
10
+ const readPkgUp = require('read-pkg-up')
11
+ const pkgConf = require('pkg-conf')
12
+ const requireMainFilename = require('require-main-filename')
13
+ const objFilter = require('./lib/obj-filter')
14
+ const setBlocking = require('set-blocking')
14
15
 
15
16
  var exports = module.exports = Yargs
16
17
  function Yargs (processArgs, cwd, parentRequire) {
17
18
  processArgs = processArgs || [] // handle calling yargs().
18
19
 
19
- var self = {}
20
+ const self = {}
20
21
  var command = null
21
22
  var completion = null
22
23
  var groups = {}
23
24
  var preservedGroups = {}
24
25
  var usage = null
25
26
  var validation = null
26
- var y18n = Y18n({
27
+ const y18n = Y18n({
27
28
  directory: path.resolve(__dirname, './locales'),
28
29
  updateFiles: false
29
30
  })
@@ -49,7 +50,7 @@ function Yargs (processArgs, cwd, parentRequire) {
49
50
 
50
51
  // use context object to keep track of resets, subcommand execution, etc
51
52
  // submodules should modify and check the state of context as necessary
52
- var context = { resets: -1, commands: [] }
53
+ const context = { resets: -1, commands: [] }
53
54
  self.getContext = function () {
54
55
  return context
55
56
  }
@@ -92,7 +93,7 @@ function Yargs (processArgs, cwd, parentRequire) {
92
93
  groups = {}
93
94
 
94
95
  var arrayOptions = [
95
- 'array', 'boolean', 'string', 'requiresArg',
96
+ 'array', 'boolean', 'string', 'requiresArg', 'skipValidation',
96
97
  'count', 'normalize', 'number'
97
98
  ]
98
99
 
@@ -175,6 +176,13 @@ function Yargs (processArgs, cwd, parentRequire) {
175
176
  }
176
177
 
177
178
  self.config = function (key, msg, parseFn) {
179
+ // allow to pass a configuration object
180
+ if (typeof key === 'object') {
181
+ options.configObjects = (options.configObjects || []).concat(key)
182
+ return self
183
+ }
184
+
185
+ // allow to provide a parsing function
178
186
  if (typeof msg === 'function') {
179
187
  parseFn = msg
180
188
  msg = null
@@ -203,7 +211,8 @@ function Yargs (processArgs, cwd, parentRequire) {
203
211
  return self
204
212
  }
205
213
 
206
- self.default = function (key, value, defaultDescription) {
214
+ // The 'defaults' alias is deprecated. It will be removed in the next major version.
215
+ self.default = self.defaults = function (key, value, defaultDescription) {
207
216
  if (typeof key === 'object') {
208
217
  Object.keys(key).forEach(function (k) {
209
218
  self.default(k, key[k])
@@ -278,6 +287,11 @@ function Yargs (processArgs, cwd, parentRequire) {
278
287
  return self
279
288
  }
280
289
 
290
+ self.skipValidation = function (skipValidations) {
291
+ options.skipValidation.push.apply(options.skipValidation, [].concat(skipValidations))
292
+ return self
293
+ }
294
+
281
295
  self.implies = function (key, value) {
282
296
  validation.implies(key, value)
283
297
  return self
@@ -311,8 +325,6 @@ function Yargs (processArgs, cwd, parentRequire) {
311
325
  return self
312
326
  }
313
327
 
314
- self.defaults = self.default
315
-
316
328
  self.describe = function (key, desc) {
317
329
  options.key[key] = true
318
330
  usage.describe(key, desc)
@@ -331,18 +343,17 @@ function Yargs (processArgs, cwd, parentRequire) {
331
343
  cwd: path || requireMainFilename(parentRequire || require)
332
344
  })
333
345
 
346
+ // If an object exists in the key, add it to options.configObjects
334
347
  if (obj.pkg && obj.pkg[key] && typeof obj.pkg[key] === 'object') {
335
348
  conf = obj.pkg[key]
336
- Object.keys(conf).forEach(function (k) {
337
- self.default(k, conf[k])
338
- })
349
+ options.configObjects = (options.configObjects || []).concat(conf)
339
350
  }
340
351
 
341
352
  return self
342
353
  }
343
354
 
344
- self.parse = function (args) {
345
- return parseArgs(args)
355
+ self.parse = function (args, shortCircuit) {
356
+ return parseArgs(args, shortCircuit)
346
357
  }
347
358
 
348
359
  self.option = self.options = function (key, opt) {
@@ -391,6 +402,8 @@ function Yargs (processArgs, cwd, parentRequire) {
391
402
  self.count(key)
392
403
  } if (opt.defaultDescription) {
393
404
  options.defaultDescription[key] = opt.defaultDescription
405
+ } if (opt.skipValidation) {
406
+ self.skipValidation(key)
394
407
  }
395
408
 
396
409
  var desc = opt.describe || opt.description || opt.desc
@@ -543,6 +556,10 @@ function Yargs (processArgs, cwd, parentRequire) {
543
556
  return self
544
557
  }
545
558
 
559
+ self.getCompletion = function (args, done) {
560
+ completion.getCompletion(args, done)
561
+ }
562
+
546
563
  self.locale = function (locale) {
547
564
  if (arguments.length === 0) {
548
565
  guessLocale()
@@ -599,14 +616,14 @@ function Yargs (processArgs, cwd, parentRequire) {
599
616
  enumerable: true
600
617
  })
601
618
 
602
- function parseArgs (args) {
619
+ function parseArgs (args, shortCircuit) {
603
620
  options.__ = y18n.__
604
621
  options.configuration = pkgConf.sync('yargs', {
605
622
  defaults: {},
606
623
  cwd: requireMainFilename(require)
607
624
  })
608
- var parsed = Parser.detailed(args, options)
609
- var argv = parsed.argv
625
+ const parsed = Parser.detailed(args, options)
626
+ const argv = parsed.argv
610
627
  var aliases = parsed.aliases
611
628
 
612
629
  argv.$0 = self.$0
@@ -617,9 +634,7 @@ function Yargs (processArgs, cwd, parentRequire) {
617
634
  // while building up the argv object, there
618
635
  // are two passes through the parser. If completion
619
636
  // is being performed short-circuit on the first pass.
620
- if (completionCommand &&
621
- (process.argv.join(' ')).indexOf(completion.completionKey) !== -1 &&
622
- !argv[completion.completionKey]) {
637
+ if (shortCircuit) {
623
638
  return argv
624
639
  }
625
640
 
@@ -635,6 +650,7 @@ function Yargs (processArgs, cwd, parentRequire) {
635
650
 
636
651
  // generate a completion script for adding to ~/.bashrc.
637
652
  if (completionCommand && ~argv._.indexOf(completionCommand) && !argv[completion.completionKey]) {
653
+ if (exitProcess) setBlocking(true)
638
654
  self.showCompletionScript()
639
655
  if (exitProcess) {
640
656
  process.exit(0)
@@ -644,9 +660,12 @@ function Yargs (processArgs, cwd, parentRequire) {
644
660
  // we must run completions first, a user might
645
661
  // want to complete the --help or --version option.
646
662
  if (completion.completionKey in argv) {
663
+ if (exitProcess) setBlocking(true)
664
+
647
665
  // we allow for asynchronous completions,
648
666
  // e.g., loading in a list of commands from an API.
649
- completion.getCompletion(function (completions) {
667
+ var completionArgs = args.slice(args.indexOf('--' + completion.completionKey) + 1)
668
+ completion.getCompletion(completionArgs, function (completions) {
650
669
  ;(completions || []).forEach(function (completion) {
651
670
  console.log(completion)
652
671
  })
@@ -658,16 +677,22 @@ function Yargs (processArgs, cwd, parentRequire) {
658
677
  return
659
678
  }
660
679
 
661
- var helpOrVersion = false
680
+ var skipValidation = false
681
+
682
+ // Handle 'help' and 'version' options
662
683
  Object.keys(argv).forEach(function (key) {
663
684
  if (key === helpOpt && argv[key]) {
664
- helpOrVersion = true
685
+ if (exitProcess) setBlocking(true)
686
+
687
+ skipValidation = true
665
688
  self.showHelp('log')
666
689
  if (exitProcess) {
667
690
  process.exit(0)
668
691
  }
669
692
  } else if (key === versionOpt && argv[key]) {
670
- helpOrVersion = true
693
+ if (exitProcess) setBlocking(true)
694
+
695
+ skipValidation = true
671
696
  usage.showVersion()
672
697
  if (exitProcess) {
673
698
  process.exit(0)
@@ -675,9 +700,16 @@ function Yargs (processArgs, cwd, parentRequire) {
675
700
  }
676
701
  })
677
702
 
703
+ // Check if any of the options to skip validation were provided
704
+ if (!skipValidation && options.skipValidation.length > 0) {
705
+ skipValidation = Object.keys(argv).some(function (key) {
706
+ return options.skipValidation.indexOf(key) >= 0
707
+ })
708
+ }
709
+
678
710
  // If the help or version options where used and exitProcess is false,
679
- // we won't run validations
680
- if (!helpOrVersion) {
711
+ // or if explicitly skipped, we won't run validations
712
+ if (!skipValidation) {
681
713
  if (parsed.error) throw parsed.error
682
714
 
683
715
  // if we're executed via bash completion, don't
@@ -702,7 +734,7 @@ function Yargs (processArgs, cwd, parentRequire) {
702
734
  if (!detectLocale) return
703
735
 
704
736
  try {
705
- var osLocale = require('os-locale')
737
+ const osLocale = require('os-locale')
706
738
  self.locale(osLocale.sync({ spawn: false }))
707
739
  } catch (err) {
708
740
  // if we explode looking up locale just noop