yargs 8.0.0 → 9.0.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 +48 -2
- package/README.md +56 -1999
- package/index.js +2 -1
- package/lib/apply-extends.js +11 -10
- package/lib/argsert.js +12 -18
- package/lib/command.js +58 -65
- package/lib/completion.js +25 -25
- package/lib/levenshtein.js +5 -5
- package/lib/obj-filter.js +4 -3
- package/lib/usage.js +105 -125
- package/lib/validation.js +124 -115
- package/lib/yerror.js +1 -0
- package/package.json +9 -16
- package/yargs.js +172 -189
- package/lib/assign.js +0 -15
package/yargs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
'use strict'
|
|
1
2
|
const argsert = require('./lib/argsert')
|
|
2
|
-
const assign = require('./lib/assign')
|
|
3
3
|
const Command = require('./lib/command')
|
|
4
4
|
const Completion = require('./lib/completion')
|
|
5
5
|
const Parser = require('yargs-parser')
|
|
@@ -12,18 +12,18 @@ const setBlocking = require('set-blocking')
|
|
|
12
12
|
const applyExtends = require('./lib/apply-extends')
|
|
13
13
|
const YError = require('./lib/yerror')
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
exports = module.exports = Yargs
|
|
16
16
|
function Yargs (processArgs, cwd, parentRequire) {
|
|
17
17
|
processArgs = processArgs || [] // handle calling yargs().
|
|
18
18
|
|
|
19
19
|
const self = {}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
let command = null
|
|
21
|
+
let completion = null
|
|
22
|
+
let groups = {}
|
|
23
|
+
let output = ''
|
|
24
|
+
let preservedGroups = {}
|
|
25
|
+
let usage = null
|
|
26
|
+
let validation = null
|
|
27
27
|
|
|
28
28
|
const y18n = Y18n({
|
|
29
29
|
directory: path.resolve(__dirname, './locales'),
|
|
@@ -34,58 +34,54 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
34
34
|
|
|
35
35
|
self.$0 = process.argv
|
|
36
36
|
.slice(0, 2)
|
|
37
|
-
.map(
|
|
37
|
+
.map((x, i) => {
|
|
38
38
|
// ignore the node bin, specify this in your
|
|
39
39
|
// bin file with #!/usr/bin/env node
|
|
40
40
|
if (i === 0 && /\b(node|iojs)(\.exe)?$/.test(x)) return
|
|
41
|
-
|
|
41
|
+
const b = rebase(cwd, x)
|
|
42
42
|
return x.match(/^(\/|([a-zA-Z]:)?\\)/) && b.length < x.length ? b : x
|
|
43
43
|
})
|
|
44
44
|
.join(' ').trim()
|
|
45
45
|
|
|
46
46
|
if (process.env._ !== undefined && process.argv[1] === process.env._) {
|
|
47
47
|
self.$0 = process.env._.replace(
|
|
48
|
-
path.dirname(process.execPath)
|
|
48
|
+
`${path.dirname(process.execPath)}/`, ''
|
|
49
49
|
)
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// use context object to keep track of resets, subcommand execution, etc
|
|
53
53
|
// submodules should modify and check the state of context as necessary
|
|
54
54
|
const context = { resets: -1, commands: [], files: [] }
|
|
55
|
-
self.getContext =
|
|
56
|
-
return context
|
|
57
|
-
}
|
|
55
|
+
self.getContext = () => context
|
|
58
56
|
|
|
59
57
|
// puts yargs back into an initial state. any keys
|
|
60
58
|
// that have been set to "global" will not be reset
|
|
61
59
|
// by this action.
|
|
62
|
-
|
|
63
|
-
self.resetOptions = self.reset = function (aliases) {
|
|
60
|
+
let options
|
|
61
|
+
self.resetOptions = self.reset = function resetOptions (aliases) {
|
|
64
62
|
context.resets++
|
|
65
63
|
aliases = aliases || {}
|
|
66
64
|
options = options || {}
|
|
67
65
|
// put yargs back into an initial state, this
|
|
68
66
|
// logic is used to build a nested command
|
|
69
67
|
// hierarchy.
|
|
70
|
-
|
|
68
|
+
const tmpOptions = {}
|
|
71
69
|
tmpOptions.local = options.local ? options.local : []
|
|
72
70
|
tmpOptions.configObjects = options.configObjects ? options.configObjects : []
|
|
73
71
|
|
|
74
72
|
// if a key has been explicitly set as local,
|
|
75
73
|
// we should reset it before passing options to command.
|
|
76
|
-
|
|
77
|
-
tmpOptions.local.forEach(
|
|
74
|
+
const localLookup = {}
|
|
75
|
+
tmpOptions.local.forEach((l) => {
|
|
78
76
|
localLookup[l] = true
|
|
79
|
-
;(aliases[l] || []).forEach(
|
|
77
|
+
;(aliases[l] || []).forEach((a) => {
|
|
80
78
|
localLookup[a] = true
|
|
81
79
|
})
|
|
82
80
|
})
|
|
83
81
|
|
|
84
82
|
// preserve all groups not set to local.
|
|
85
|
-
preservedGroups = Object.keys(groups).reduce(
|
|
86
|
-
|
|
87
|
-
return !(key in localLookup)
|
|
88
|
-
})
|
|
83
|
+
preservedGroups = Object.keys(groups).reduce((acc, groupName) => {
|
|
84
|
+
const keys = groups[groupName].filter(key => !(key in localLookup))
|
|
89
85
|
if (keys.length > 0) {
|
|
90
86
|
acc[groupName] = keys
|
|
91
87
|
}
|
|
@@ -94,26 +90,22 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
94
90
|
// groups can now be reset
|
|
95
91
|
groups = {}
|
|
96
92
|
|
|
97
|
-
|
|
93
|
+
const arrayOptions = [
|
|
98
94
|
'array', 'boolean', 'string', 'requiresArg', 'skipValidation',
|
|
99
95
|
'count', 'normalize', 'number'
|
|
100
96
|
]
|
|
101
97
|
|
|
102
|
-
|
|
98
|
+
const objectOptions = [
|
|
103
99
|
'narg', 'key', 'alias', 'default', 'defaultDescription',
|
|
104
100
|
'config', 'choices', 'demandedOptions', 'demandedCommands', 'coerce'
|
|
105
101
|
]
|
|
106
102
|
|
|
107
|
-
arrayOptions.forEach(
|
|
108
|
-
tmpOptions[k] = (options[k] || []).filter(
|
|
109
|
-
return !localLookup[k]
|
|
110
|
-
})
|
|
103
|
+
arrayOptions.forEach((k) => {
|
|
104
|
+
tmpOptions[k] = (options[k] || []).filter(k => !localLookup[k])
|
|
111
105
|
})
|
|
112
106
|
|
|
113
|
-
objectOptions.forEach(
|
|
114
|
-
tmpOptions[k] = objFilter(options[k],
|
|
115
|
-
return !localLookup[k]
|
|
116
|
-
})
|
|
107
|
+
objectOptions.forEach((k) => {
|
|
108
|
+
tmpOptions[k] = objFilter(options[k], (k, v) => !localLookup[k])
|
|
117
109
|
})
|
|
118
110
|
|
|
119
111
|
tmpOptions.envPrefix = options.envPrefix
|
|
@@ -137,7 +129,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
137
129
|
self.resetOptions()
|
|
138
130
|
|
|
139
131
|
// temporary hack: allow "freezing" of reset-able state for parse(msg, cb)
|
|
140
|
-
|
|
132
|
+
let frozen
|
|
141
133
|
function freeze () {
|
|
142
134
|
frozen = {}
|
|
143
135
|
frozen.options = options
|
|
@@ -223,7 +215,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
223
215
|
|
|
224
216
|
function populateParserHintArray (type, keys, value) {
|
|
225
217
|
keys = [].concat(keys)
|
|
226
|
-
keys.forEach(
|
|
218
|
+
keys.forEach((key) => {
|
|
227
219
|
options[type].push(key)
|
|
228
220
|
})
|
|
229
221
|
}
|
|
@@ -280,14 +272,14 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
280
272
|
function populateParserHintObject (builder, isArray, type, key, value) {
|
|
281
273
|
if (Array.isArray(key)) {
|
|
282
274
|
// an array of keys with one value ['x', 'y', 'z'], function parse () {}
|
|
283
|
-
|
|
284
|
-
key.forEach(
|
|
275
|
+
const temp = {}
|
|
276
|
+
key.forEach((k) => {
|
|
285
277
|
temp[k] = value
|
|
286
278
|
})
|
|
287
279
|
builder(temp)
|
|
288
280
|
} else if (typeof key === 'object') {
|
|
289
281
|
// an object of key value pairs: {'x': parse () {}, 'y': parse() {}}
|
|
290
|
-
Object.keys(key).forEach(
|
|
282
|
+
Object.keys(key).forEach((k) => {
|
|
291
283
|
builder(k, key[k])
|
|
292
284
|
})
|
|
293
285
|
} else {
|
|
@@ -300,7 +292,22 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
300
292
|
}
|
|
301
293
|
}
|
|
302
294
|
|
|
303
|
-
|
|
295
|
+
function deleteFromParserHintObject (optionKey) {
|
|
296
|
+
// delete from all parsing hints:
|
|
297
|
+
// boolean, array, key, alias, etc.
|
|
298
|
+
Object.keys(options).forEach((hintKey) => {
|
|
299
|
+
const hint = options[hintKey]
|
|
300
|
+
if (Array.isArray(hint)) {
|
|
301
|
+
if (~hint.indexOf(optionKey)) hint.splice(hint.indexOf(optionKey), 1)
|
|
302
|
+
} else if (typeof hint === 'object') {
|
|
303
|
+
delete hint[optionKey]
|
|
304
|
+
}
|
|
305
|
+
})
|
|
306
|
+
// now delete the description from usage.js.
|
|
307
|
+
delete usage.getDescriptions()[optionKey]
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
self.config = function config (key, msg, parseFn) {
|
|
304
311
|
argsert('[object|string] [string|function] [function]', [key, msg, parseFn], arguments.length)
|
|
305
312
|
// allow a config object to be provided directly.
|
|
306
313
|
if (typeof key === 'object') {
|
|
@@ -317,7 +324,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
317
324
|
|
|
318
325
|
key = key || 'config'
|
|
319
326
|
self.describe(key, msg || usage.deferY18nLookup('Path to JSON config file'))
|
|
320
|
-
;(Array.isArray(key) ? key : [key]).forEach(
|
|
327
|
+
;(Array.isArray(key) ? key : [key]).forEach((k) => {
|
|
321
328
|
options.config[k] = parseFn || true
|
|
322
329
|
})
|
|
323
330
|
|
|
@@ -345,12 +352,12 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
345
352
|
|
|
346
353
|
// TODO: deprecate self.demand in favor of
|
|
347
354
|
// .demandCommand() .demandOption().
|
|
348
|
-
self.demand = self.required = self.require = function (keys, max, msg) {
|
|
355
|
+
self.demand = self.required = self.require = function demand (keys, max, msg) {
|
|
349
356
|
// you can optionally provide a 'max' key,
|
|
350
357
|
// which will raise an exception if too many '_'
|
|
351
358
|
// options are provided.
|
|
352
359
|
if (Array.isArray(max)) {
|
|
353
|
-
max.forEach(
|
|
360
|
+
max.forEach((key) => {
|
|
354
361
|
self.demandOption(key, msg)
|
|
355
362
|
})
|
|
356
363
|
max = Infinity
|
|
@@ -362,7 +369,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
362
369
|
if (typeof keys === 'number') {
|
|
363
370
|
self.demandCommand(keys, max, msg, msg)
|
|
364
371
|
} else if (Array.isArray(keys)) {
|
|
365
|
-
keys.forEach(
|
|
372
|
+
keys.forEach((key) => {
|
|
366
373
|
self.demandOption(key, msg)
|
|
367
374
|
})
|
|
368
375
|
} else {
|
|
@@ -376,8 +383,8 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
376
383
|
return self
|
|
377
384
|
}
|
|
378
385
|
|
|
379
|
-
self.demandCommand = function (min, max, minMsg, maxMsg) {
|
|
380
|
-
argsert('[number] [number|string] [string|null] [string|null]', [min, max, minMsg, maxMsg], arguments.length)
|
|
386
|
+
self.demandCommand = function demandCommand (min, max, minMsg, maxMsg) {
|
|
387
|
+
argsert('[number] [number|string] [string|null|undefined] [string|null|undefined]', [min, max, minMsg, maxMsg], arguments.length)
|
|
381
388
|
|
|
382
389
|
if (typeof min === 'undefined') min = 1
|
|
383
390
|
|
|
@@ -389,39 +396,39 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
389
396
|
self.global('_', false)
|
|
390
397
|
|
|
391
398
|
options.demandedCommands._ = {
|
|
392
|
-
min
|
|
393
|
-
max
|
|
394
|
-
minMsg
|
|
395
|
-
maxMsg
|
|
399
|
+
min,
|
|
400
|
+
max,
|
|
401
|
+
minMsg,
|
|
402
|
+
maxMsg
|
|
396
403
|
}
|
|
397
404
|
|
|
398
405
|
return self
|
|
399
406
|
}
|
|
400
407
|
|
|
401
|
-
self.getDemandedOptions =
|
|
408
|
+
self.getDemandedOptions = () => {
|
|
402
409
|
argsert([], 0)
|
|
403
410
|
return options.demandedOptions
|
|
404
411
|
}
|
|
405
412
|
|
|
406
|
-
self.getDemandedCommands =
|
|
413
|
+
self.getDemandedCommands = () => {
|
|
407
414
|
argsert([], 0)
|
|
408
415
|
return options.demandedCommands
|
|
409
416
|
}
|
|
410
417
|
|
|
411
418
|
self.implies = function (key, value) {
|
|
412
|
-
argsert('<string|object> [string]', [key, value], arguments.length)
|
|
419
|
+
argsert('<string|object> [number|string|array]', [key, value], arguments.length)
|
|
413
420
|
validation.implies(key, value)
|
|
414
421
|
return self
|
|
415
422
|
}
|
|
416
423
|
|
|
417
424
|
self.conflicts = function (key1, key2) {
|
|
418
|
-
argsert('<string|object> [string]', [key1, key2], arguments.length)
|
|
425
|
+
argsert('<string|object> [string|array]', [key1, key2], arguments.length)
|
|
419
426
|
validation.conflicts(key1, key2)
|
|
420
427
|
return self
|
|
421
428
|
}
|
|
422
429
|
|
|
423
430
|
self.usage = function (msg, opts) {
|
|
424
|
-
argsert('<string|null|object> [object]', [msg, opts], arguments.length)
|
|
431
|
+
argsert('<string|null|undefined|object> [object]', [msg, opts], arguments.length)
|
|
425
432
|
|
|
426
433
|
if (!opts && typeof msg === 'object') {
|
|
427
434
|
opts = msg
|
|
@@ -453,28 +460,26 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
453
460
|
return self
|
|
454
461
|
}
|
|
455
462
|
|
|
456
|
-
self.global = function (globals, global) {
|
|
463
|
+
self.global = function global (globals, global) {
|
|
457
464
|
argsert('<string|array> [boolean]', [globals, global], arguments.length)
|
|
458
465
|
globals = [].concat(globals)
|
|
459
466
|
if (global !== false) {
|
|
460
|
-
options.local = options.local.filter(
|
|
461
|
-
return globals.indexOf(l) === -1
|
|
462
|
-
})
|
|
467
|
+
options.local = options.local.filter(l => globals.indexOf(l) === -1)
|
|
463
468
|
} else {
|
|
464
|
-
globals.forEach(
|
|
469
|
+
globals.forEach((g) => {
|
|
465
470
|
if (options.local.indexOf(g) === -1) options.local.push(g)
|
|
466
471
|
})
|
|
467
472
|
}
|
|
468
473
|
return self
|
|
469
474
|
}
|
|
470
475
|
|
|
471
|
-
self.pkgConf = function (key, path) {
|
|
476
|
+
self.pkgConf = function pkgConf (key, path) {
|
|
472
477
|
argsert('<string> [string]', [key, path], arguments.length)
|
|
473
|
-
|
|
478
|
+
let conf = null
|
|
474
479
|
// prefer cwd to require-main-filename in this method
|
|
475
480
|
// since we're looking for e.g. "nyc" config in nyc consumer
|
|
476
481
|
// rather than "yargs" config in nyc (where nyc is the main filename)
|
|
477
|
-
|
|
482
|
+
const obj = pkgUp(path || cwd)
|
|
478
483
|
|
|
479
484
|
// If an object exists in the key, add it to options.configObjects
|
|
480
485
|
if (obj[key] && typeof obj[key] === 'object') {
|
|
@@ -485,13 +490,13 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
485
490
|
return self
|
|
486
491
|
}
|
|
487
492
|
|
|
488
|
-
|
|
493
|
+
const pkgs = {}
|
|
489
494
|
function pkgUp (path) {
|
|
490
|
-
|
|
495
|
+
const npath = path || '*'
|
|
491
496
|
if (pkgs[npath]) return pkgs[npath]
|
|
492
497
|
const readPkgUp = require('read-pkg-up')
|
|
493
498
|
|
|
494
|
-
|
|
499
|
+
let obj = {}
|
|
495
500
|
try {
|
|
496
501
|
obj = readPkgUp.sync({
|
|
497
502
|
cwd: path || require('require-main-filename')(parentRequire || require),
|
|
@@ -503,10 +508,11 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
503
508
|
return pkgs[npath]
|
|
504
509
|
}
|
|
505
510
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
self.parse = function (args, shortCircuit, _parseFn) {
|
|
509
|
-
argsert('
|
|
511
|
+
let parseFn = null
|
|
512
|
+
let parseContext = null
|
|
513
|
+
self.parse = function parse (args, shortCircuit, _parseFn) {
|
|
514
|
+
argsert('[string|array] [function|boolean|object] [function]', [args, shortCircuit, _parseFn], arguments.length)
|
|
515
|
+
if (typeof args === 'undefined') args = processArgs
|
|
510
516
|
|
|
511
517
|
// a context object can optionally be provided, this allows
|
|
512
518
|
// additional information to be passed to a command handler.
|
|
@@ -529,25 +535,21 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
529
535
|
freeze()
|
|
530
536
|
if (parseFn) exitProcess = false
|
|
531
537
|
|
|
532
|
-
|
|
538
|
+
const parsed = self._parseArgs(args, shortCircuit)
|
|
533
539
|
if (parseFn) parseFn(exitError, parsed, output)
|
|
534
540
|
unfreeze()
|
|
535
541
|
|
|
536
542
|
return parsed
|
|
537
543
|
}
|
|
538
544
|
|
|
539
|
-
self._getParseContext =
|
|
540
|
-
return parseContext || {}
|
|
541
|
-
}
|
|
545
|
+
self._getParseContext = () => parseContext || {}
|
|
542
546
|
|
|
543
|
-
self._hasParseCallback =
|
|
544
|
-
return !!parseFn
|
|
545
|
-
}
|
|
547
|
+
self._hasParseCallback = () => !!parseFn
|
|
546
548
|
|
|
547
|
-
self.option = self.options = function (key, opt) {
|
|
549
|
+
self.option = self.options = function option (key, opt) {
|
|
548
550
|
argsert('<string|object> [object]', [key, opt], arguments.length)
|
|
549
551
|
if (typeof key === 'object') {
|
|
550
|
-
Object.keys(key).forEach(
|
|
552
|
+
Object.keys(key).forEach((k) => {
|
|
551
553
|
self.options(k, key[k])
|
|
552
554
|
})
|
|
553
555
|
} else {
|
|
@@ -559,7 +561,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
559
561
|
|
|
560
562
|
if (opt.alias) self.alias(key, opt.alias)
|
|
561
563
|
|
|
562
|
-
|
|
564
|
+
const demand = opt.demand || opt.required || opt.require
|
|
563
565
|
|
|
564
566
|
// deprecated, use 'demandOption' instead
|
|
565
567
|
if (demand) {
|
|
@@ -642,7 +644,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
642
644
|
self.skipValidation(key)
|
|
643
645
|
}
|
|
644
646
|
|
|
645
|
-
|
|
647
|
+
const desc = opt.describe || opt.description || opt.desc
|
|
646
648
|
if (desc) {
|
|
647
649
|
self.describe(key, desc)
|
|
648
650
|
}
|
|
@@ -654,29 +656,25 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
654
656
|
|
|
655
657
|
return self
|
|
656
658
|
}
|
|
657
|
-
self.getOptions =
|
|
658
|
-
return options
|
|
659
|
-
}
|
|
659
|
+
self.getOptions = () => options
|
|
660
660
|
|
|
661
|
-
self.group = function (opts, groupName) {
|
|
661
|
+
self.group = function group (opts, groupName) {
|
|
662
662
|
argsert('<string|array> <string>', [opts, groupName], arguments.length)
|
|
663
|
-
|
|
663
|
+
const existing = preservedGroups[groupName] || groups[groupName]
|
|
664
664
|
if (preservedGroups[groupName]) {
|
|
665
665
|
// we now only need to track this group name in groups.
|
|
666
666
|
delete preservedGroups[groupName]
|
|
667
667
|
}
|
|
668
668
|
|
|
669
|
-
|
|
670
|
-
groups[groupName] = (existing || []).concat(opts).filter(
|
|
669
|
+
const seen = {}
|
|
670
|
+
groups[groupName] = (existing || []).concat(opts).filter((key) => {
|
|
671
671
|
if (seen[key]) return false
|
|
672
672
|
return (seen[key] = true)
|
|
673
673
|
})
|
|
674
674
|
return self
|
|
675
675
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
return assign(groups, preservedGroups)
|
|
679
|
-
}
|
|
676
|
+
// combine explicit and preserved groups. explicit groups should be first
|
|
677
|
+
self.getGroups = () => Object.assign({}, groups, preservedGroups)
|
|
680
678
|
|
|
681
679
|
// as long as options.envPrefix is not undefined,
|
|
682
680
|
// parser will apply env vars matching prefix to argv
|
|
@@ -688,20 +686,18 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
688
686
|
}
|
|
689
687
|
|
|
690
688
|
self.wrap = function (cols) {
|
|
691
|
-
argsert('<number|null>', [cols], arguments.length)
|
|
689
|
+
argsert('<number|null|undefined>', [cols], arguments.length)
|
|
692
690
|
usage.wrap(cols)
|
|
693
691
|
return self
|
|
694
692
|
}
|
|
695
693
|
|
|
696
|
-
|
|
694
|
+
let strict = false
|
|
697
695
|
self.strict = function (enabled) {
|
|
698
696
|
argsert('[boolean]', [enabled], arguments.length)
|
|
699
697
|
strict = enabled !== false
|
|
700
698
|
return self
|
|
701
699
|
}
|
|
702
|
-
self.getStrict =
|
|
703
|
-
return strict
|
|
704
|
-
}
|
|
700
|
+
self.getStrict = () => strict
|
|
705
701
|
|
|
706
702
|
self.showHelp = function (level) {
|
|
707
703
|
argsert('[string|function]', [level], arguments.length)
|
|
@@ -710,21 +706,34 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
710
706
|
return self
|
|
711
707
|
}
|
|
712
708
|
|
|
713
|
-
|
|
714
|
-
self.version = function (opt, msg, ver) {
|
|
715
|
-
|
|
709
|
+
let versionOpt = null
|
|
710
|
+
self.version = function version (opt, msg, ver) {
|
|
711
|
+
const defaultVersionOpt = 'version'
|
|
712
|
+
argsert('[boolean|string] [string] [string]', [opt, msg, ver], arguments.length)
|
|
713
|
+
|
|
714
|
+
// nuke the key previously configured
|
|
715
|
+
// to return version #.
|
|
716
|
+
if (versionOpt) {
|
|
717
|
+
deleteFromParserHintObject(versionOpt)
|
|
718
|
+
usage.version(undefined)
|
|
719
|
+
versionOpt = null
|
|
720
|
+
}
|
|
721
|
+
|
|
716
722
|
if (arguments.length === 0) {
|
|
717
723
|
ver = guessVersion()
|
|
718
|
-
opt =
|
|
724
|
+
opt = defaultVersionOpt
|
|
719
725
|
} else if (arguments.length === 1) {
|
|
726
|
+
if (opt === false) { // disable default 'version' key.
|
|
727
|
+
return self
|
|
728
|
+
}
|
|
720
729
|
ver = opt
|
|
721
|
-
opt =
|
|
730
|
+
opt = defaultVersionOpt
|
|
722
731
|
} else if (arguments.length === 2) {
|
|
723
732
|
ver = msg
|
|
724
733
|
msg = null
|
|
725
734
|
}
|
|
726
735
|
|
|
727
|
-
versionOpt = opt
|
|
736
|
+
versionOpt = typeof opt === 'string' ? opt : defaultVersionOpt
|
|
728
737
|
msg = msg || usage.deferY18nLookup('Show version number')
|
|
729
738
|
|
|
730
739
|
usage.version(ver || undefined)
|
|
@@ -734,44 +743,35 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
734
743
|
}
|
|
735
744
|
|
|
736
745
|
function guessVersion () {
|
|
737
|
-
|
|
746
|
+
const obj = pkgUp()
|
|
738
747
|
|
|
739
748
|
return obj.version || 'unknown'
|
|
740
749
|
}
|
|
741
750
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
argsert('[string|boolean] [string
|
|
751
|
+
let helpOpt = null
|
|
752
|
+
self.addHelpOpt = self.help = function addHelpOpt (opt, msg) {
|
|
753
|
+
const defaultHelpOpt = 'help'
|
|
754
|
+
argsert('[string|boolean] [string]', [opt, msg], arguments.length)
|
|
746
755
|
|
|
747
|
-
//
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
}
|
|
757
|
-
} else if (arguments.length === 2) {
|
|
758
|
-
if (typeof msg === 'boolean') {
|
|
759
|
-
useHelpOptAsCommand = msg
|
|
760
|
-
msg = null
|
|
761
|
-
} else {
|
|
762
|
-
useHelpOptAsCommand = true
|
|
763
|
-
}
|
|
764
|
-
} else {
|
|
765
|
-
useHelpOptAsCommand = Boolean(addImplicitCmd)
|
|
756
|
+
// nuke the key previously configured
|
|
757
|
+
// to return help.
|
|
758
|
+
if (helpOpt) {
|
|
759
|
+
deleteFromParserHintObject(helpOpt)
|
|
760
|
+
helpOpt = null
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
if (arguments.length === 1) {
|
|
764
|
+
if (opt === false) return self
|
|
766
765
|
}
|
|
766
|
+
|
|
767
767
|
// use arguments, fallback to defaults for opt and msg
|
|
768
|
-
helpOpt = opt
|
|
768
|
+
helpOpt = typeof opt === 'string' ? opt : defaultHelpOpt
|
|
769
769
|
self.boolean(helpOpt)
|
|
770
770
|
self.describe(helpOpt, msg || usage.deferY18nLookup('Show help'))
|
|
771
771
|
return self
|
|
772
772
|
}
|
|
773
773
|
|
|
774
|
-
self.showHelpOnFail = function (enabled, message) {
|
|
774
|
+
self.showHelpOnFail = function showHelpOnFail (enabled, message) {
|
|
775
775
|
argsert('[boolean|string] [string]', [enabled, message], arguments.length)
|
|
776
776
|
usage.showHelpOnFail(enabled, message)
|
|
777
777
|
return self
|
|
@@ -786,9 +786,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
786
786
|
exitProcess = enabled
|
|
787
787
|
return self
|
|
788
788
|
}
|
|
789
|
-
self.getExitProcess =
|
|
790
|
-
return exitProcess
|
|
791
|
-
}
|
|
789
|
+
self.getExitProcess = () => exitProcess
|
|
792
790
|
|
|
793
791
|
var completionCommand = null
|
|
794
792
|
self.completion = function (cmd, desc, fn) {
|
|
@@ -845,21 +843,19 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
845
843
|
return self
|
|
846
844
|
}
|
|
847
845
|
|
|
848
|
-
|
|
846
|
+
let detectLocale = true
|
|
849
847
|
self.detectLocale = function (detect) {
|
|
850
848
|
argsert('<boolean>', [detect], arguments.length)
|
|
851
849
|
detectLocale = detect
|
|
852
850
|
return self
|
|
853
851
|
}
|
|
854
|
-
self.getDetectLocale =
|
|
855
|
-
return detectLocale
|
|
856
|
-
}
|
|
852
|
+
self.getDetectLocale = () => detectLocale
|
|
857
853
|
|
|
858
854
|
var hasOutput = false
|
|
859
855
|
var exitError = null
|
|
860
856
|
// maybe exit, always capture
|
|
861
857
|
// context about why we wanted to exit.
|
|
862
|
-
self.exit =
|
|
858
|
+
self.exit = (code, err) => {
|
|
863
859
|
hasOutput = true
|
|
864
860
|
exitError = err
|
|
865
861
|
if (exitProcess) process.exit(code)
|
|
@@ -867,78 +863,66 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
867
863
|
|
|
868
864
|
// we use a custom logger that buffers output,
|
|
869
865
|
// so that we can print to non-CLIs, e.g., chat-bots.
|
|
870
|
-
|
|
871
|
-
log
|
|
866
|
+
const _logger = {
|
|
867
|
+
log () {
|
|
872
868
|
const args = []
|
|
873
|
-
for (
|
|
869
|
+
for (let i = 0; i < arguments.length; i++) args.push(arguments[i])
|
|
874
870
|
if (!self._hasParseCallback()) console.log.apply(console, args)
|
|
875
871
|
hasOutput = true
|
|
876
872
|
if (output.length) output += '\n'
|
|
877
873
|
output += args.join(' ')
|
|
878
874
|
},
|
|
879
|
-
error
|
|
875
|
+
error () {
|
|
880
876
|
const args = []
|
|
881
|
-
for (
|
|
877
|
+
for (let i = 0; i < arguments.length; i++) args.push(arguments[i])
|
|
882
878
|
if (!self._hasParseCallback()) console.error.apply(console, args)
|
|
883
879
|
hasOutput = true
|
|
884
880
|
if (output.length) output += '\n'
|
|
885
881
|
output += args.join(' ')
|
|
886
882
|
}
|
|
887
883
|
}
|
|
888
|
-
self._getLoggerInstance =
|
|
889
|
-
return _logger
|
|
890
|
-
}
|
|
884
|
+
self._getLoggerInstance = () => _logger
|
|
891
885
|
// has yargs output an error our help
|
|
892
886
|
// message in the current execution context.
|
|
893
|
-
self._hasOutput =
|
|
894
|
-
return hasOutput
|
|
895
|
-
}
|
|
887
|
+
self._hasOutput = () => hasOutput
|
|
896
888
|
|
|
897
|
-
self._setHasOutput =
|
|
889
|
+
self._setHasOutput = () => {
|
|
898
890
|
hasOutput = true
|
|
899
891
|
}
|
|
900
892
|
|
|
901
|
-
|
|
893
|
+
let recommendCommands
|
|
902
894
|
self.recommendCommands = function (recommend) {
|
|
903
895
|
argsert('[boolean]', [recommend], arguments.length)
|
|
904
896
|
recommendCommands = typeof recommend === 'boolean' ? recommend : true
|
|
905
897
|
return self
|
|
906
898
|
}
|
|
907
899
|
|
|
908
|
-
self.getUsageInstance =
|
|
909
|
-
return usage
|
|
910
|
-
}
|
|
900
|
+
self.getUsageInstance = () => usage
|
|
911
901
|
|
|
912
|
-
self.getValidationInstance =
|
|
913
|
-
return validation
|
|
914
|
-
}
|
|
902
|
+
self.getValidationInstance = () => validation
|
|
915
903
|
|
|
916
|
-
self.getCommandInstance =
|
|
917
|
-
return command
|
|
918
|
-
}
|
|
904
|
+
self.getCommandInstance = () => command
|
|
919
905
|
|
|
920
|
-
self.terminalWidth =
|
|
906
|
+
self.terminalWidth = () => {
|
|
921
907
|
argsert([], 0)
|
|
922
908
|
return typeof process.stdout.columns !== 'undefined' ? process.stdout.columns : null
|
|
923
909
|
}
|
|
924
910
|
|
|
925
911
|
Object.defineProperty(self, 'argv', {
|
|
926
|
-
get:
|
|
927
|
-
return self._parseArgs(processArgs)
|
|
928
|
-
},
|
|
912
|
+
get: () => self._parseArgs(processArgs),
|
|
929
913
|
enumerable: true
|
|
930
914
|
})
|
|
931
915
|
|
|
932
|
-
self._parseArgs = function (args, shortCircuit, _skipValidation, commandIndex) {
|
|
933
|
-
|
|
916
|
+
self._parseArgs = function parseArgs (args, shortCircuit, _skipValidation, commandIndex) {
|
|
917
|
+
let skipValidation = !!_skipValidation
|
|
934
918
|
args = args || processArgs
|
|
935
919
|
|
|
936
920
|
options.__ = y18n.__
|
|
937
921
|
options.configuration = pkgUp()['yargs'] || {}
|
|
938
922
|
const parsed = Parser.detailed(args, options)
|
|
939
|
-
|
|
940
|
-
if (parseContext) argv = assign(argv, parseContext)
|
|
941
|
-
|
|
923
|
+
let argv = parsed.argv
|
|
924
|
+
if (parseContext) argv = Object.assign({}, argv, parseContext)
|
|
925
|
+
const aliases = parsed.aliases
|
|
942
926
|
|
|
943
927
|
argv.$0 = self.$0
|
|
944
928
|
self.parsed = parsed
|
|
@@ -954,19 +938,15 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
954
938
|
}
|
|
955
939
|
|
|
956
940
|
if (argv._.length) {
|
|
957
|
-
|
|
958
|
-
// assumes helpOpt must be valid if useHelpOptAsCommand is true
|
|
959
|
-
if (useHelpOptAsCommand) {
|
|
941
|
+
if (helpOpt) {
|
|
960
942
|
// consider any multi-char helpOpt alias as a valid help command
|
|
961
943
|
// unless all helpOpt aliases are single-char
|
|
962
944
|
// note that parsed.aliases is a normalized bidirectional map :)
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
return k.length > 1
|
|
966
|
-
})
|
|
945
|
+
let helpCmds = [helpOpt].concat(aliases[helpOpt] || [])
|
|
946
|
+
const multiCharHelpCmds = helpCmds.filter(k => k.length > 1)
|
|
967
947
|
if (multiCharHelpCmds.length) helpCmds = multiCharHelpCmds
|
|
968
948
|
// look for and strip any helpCmds from argv._
|
|
969
|
-
argv._ = argv._.filter(
|
|
949
|
+
argv._ = argv._.filter((cmd) => {
|
|
970
950
|
if (~helpCmds.indexOf(cmd)) {
|
|
971
951
|
argv[helpOpt] = true
|
|
972
952
|
return false
|
|
@@ -977,10 +957,10 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
977
957
|
|
|
978
958
|
// if there's a handler associated with a
|
|
979
959
|
// command defer processing to it.
|
|
980
|
-
|
|
960
|
+
const handlerKeys = command.getCommands()
|
|
981
961
|
if (handlerKeys.length) {
|
|
982
|
-
|
|
983
|
-
for (
|
|
962
|
+
let firstUnknownCommand
|
|
963
|
+
for (let i = (commandIndex || 0), cmd; argv._[i] !== undefined; i++) {
|
|
984
964
|
cmd = String(argv._[i])
|
|
985
965
|
if (~handlerKeys.indexOf(cmd) && cmd !== completionCommand) {
|
|
986
966
|
setPlaceholderKeys(argv)
|
|
@@ -1025,9 +1005,9 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
1025
1005
|
|
|
1026
1006
|
// we allow for asynchronous completions,
|
|
1027
1007
|
// e.g., loading in a list of commands from an API.
|
|
1028
|
-
|
|
1029
|
-
completion.getCompletion(completionArgs,
|
|
1030
|
-
;(completions || []).forEach(
|
|
1008
|
+
const completionArgs = args.slice(args.indexOf(`--${completion.completionKey}`) + 1)
|
|
1009
|
+
completion.getCompletion(completionArgs, (completions) => {
|
|
1010
|
+
;(completions || []).forEach((completion) => {
|
|
1031
1011
|
_logger.log(completion)
|
|
1032
1012
|
})
|
|
1033
1013
|
|
|
@@ -1039,7 +1019,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
1039
1019
|
// Handle 'help' and 'version' options
|
|
1040
1020
|
// if we haven't already output help!
|
|
1041
1021
|
if (!hasOutput) {
|
|
1042
|
-
Object.keys(argv).forEach(
|
|
1022
|
+
Object.keys(argv).forEach((key) => {
|
|
1043
1023
|
if (key === helpOpt && argv[key]) {
|
|
1044
1024
|
if (exitProcess) setBlocking(true)
|
|
1045
1025
|
|
|
@@ -1058,9 +1038,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
1058
1038
|
|
|
1059
1039
|
// Check if any of the options to skip validation were provided
|
|
1060
1040
|
if (!skipValidation && options.skipValidation.length > 0) {
|
|
1061
|
-
skipValidation = Object.keys(argv).some(
|
|
1062
|
-
return options.skipValidation.indexOf(key) >= 0 && argv[key] === true
|
|
1063
|
-
})
|
|
1041
|
+
skipValidation = Object.keys(argv).some(key => options.skipValidation.indexOf(key) >= 0 && argv[key] === true)
|
|
1064
1042
|
}
|
|
1065
1043
|
|
|
1066
1044
|
// If the help or version options where used and exitProcess is false,
|
|
@@ -1082,7 +1060,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
1082
1060
|
return setPlaceholderKeys(argv)
|
|
1083
1061
|
}
|
|
1084
1062
|
|
|
1085
|
-
self._runValidation = function (argv, aliases, positionalMap, parseErrors) {
|
|
1063
|
+
self._runValidation = function runValidation (argv, aliases, positionalMap, parseErrors) {
|
|
1086
1064
|
if (parseErrors) throw new YError(parseErrors.message)
|
|
1087
1065
|
validation.nonOptionCount(argv)
|
|
1088
1066
|
validation.missingArgumentValue(argv)
|
|
@@ -1107,7 +1085,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
1107
1085
|
}
|
|
1108
1086
|
|
|
1109
1087
|
function setPlaceholderKeys (argv) {
|
|
1110
|
-
Object.keys(options.key).forEach(
|
|
1088
|
+
Object.keys(options.key).forEach((key) => {
|
|
1111
1089
|
// don't set placeholder keys for dot
|
|
1112
1090
|
// notation options 'foo.bar'.
|
|
1113
1091
|
if (~key.indexOf('.')) return
|
|
@@ -1116,6 +1094,11 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
1116
1094
|
return argv
|
|
1117
1095
|
}
|
|
1118
1096
|
|
|
1097
|
+
// an app should almost always have --version and --help,
|
|
1098
|
+
// if you *really* want to disable this use .help(false)/.version(false).
|
|
1099
|
+
self.help()
|
|
1100
|
+
self.version()
|
|
1101
|
+
|
|
1119
1102
|
return self
|
|
1120
1103
|
}
|
|
1121
1104
|
|