yargs 13.3.0 → 14.2.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 +58 -0
- package/README.md +16 -2
- package/index.js +8 -1
- package/lib/apply-extends.js +18 -4
- package/lib/command.js +29 -27
- package/lib/completion.js +2 -1
- package/lib/is-promise.js +1 -1
- package/lib/middleware.js +1 -2
- package/lib/usage.js +21 -12
- package/lib/validation.js +42 -33
- package/package.json +4 -3
- package/yargs.js +35 -23
- package/lib/decamelize.js +0 -32
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,64 @@
|
|
|
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
|
+
## [14.2.0](https://github.com/yargs/yargs/compare/v14.1.0...v14.2.0) (2019-10-07)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* async middleware was called twice ([#1422](https://github.com/yargs/yargs/issues/1422)) ([9a42b63](https://github.com/yargs/yargs/commit/9a42b63))
|
|
11
|
+
* fix promise check to accept any spec conform object ([#1424](https://github.com/yargs/yargs/issues/1424)) ([0be43d2](https://github.com/yargs/yargs/commit/0be43d2))
|
|
12
|
+
* groups were not being maintained for nested commands ([#1430](https://github.com/yargs/yargs/issues/1430)) ([d38650e](https://github.com/yargs/yargs/commit/d38650e))
|
|
13
|
+
* **docs:** broken markdown link ([#1426](https://github.com/yargs/yargs/issues/1426)) ([236e24e](https://github.com/yargs/yargs/commit/236e24e))
|
|
14
|
+
* support merging deeply nested configuration ([#1423](https://github.com/yargs/yargs/issues/1423)) ([bae66fe](https://github.com/yargs/yargs/commit/bae66fe))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* **deps:** introduce yargs-parser with support for unknown-options-as-args ([#1440](https://github.com/yargs/yargs/issues/1440)) ([4d21520](https://github.com/yargs/yargs/commit/4d21520))
|
|
20
|
+
|
|
21
|
+
## [14.1.0](https://github.com/yargs/yargs/compare/v14.0.0...v14.1.0) (2019-09-06)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* **docs:** fix incorrect parserConfiguration documentation ([2a99124](https://github.com/yargs/yargs/commit/2a99124))
|
|
27
|
+
* detect zsh when zsh isnt run as a login prompt ([#1395](https://github.com/yargs/yargs/issues/1395)) ([8792d13](https://github.com/yargs/yargs/commit/8792d13))
|
|
28
|
+
* populate correct value on yargs.parsed and stop warning on access ([#1412](https://github.com/yargs/yargs/issues/1412)) ([bb0eb52](https://github.com/yargs/yargs/commit/bb0eb52))
|
|
29
|
+
* showCompletionScript was logging script twice ([#1388](https://github.com/yargs/yargs/issues/1388)) ([07c8537](https://github.com/yargs/yargs/commit/07c8537))
|
|
30
|
+
* strict() should not ignore hyphenated arguments ([#1414](https://github.com/yargs/yargs/issues/1414)) ([b774b5e](https://github.com/yargs/yargs/commit/b774b5e))
|
|
31
|
+
* **docs:** formalize existing callback argument to showHelp ([#1386](https://github.com/yargs/yargs/issues/1386)) ([d217764](https://github.com/yargs/yargs/commit/d217764))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Features
|
|
35
|
+
|
|
36
|
+
* make it possible to merge configurations when extending other config. ([#1411](https://github.com/yargs/yargs/issues/1411)) ([5d7ad98](https://github.com/yargs/yargs/commit/5d7ad98))
|
|
37
|
+
|
|
38
|
+
## [14.0.0](https://github.com/yargs/yargs/compare/v13.3.0...v14.0.0) (2019-07-30)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
### ⚠ BREAKING CHANGES
|
|
42
|
+
|
|
43
|
+
* we now only officially support yargs.$0 parameter and discourage direct access to yargs.parsed
|
|
44
|
+
* previously to this fix methods like `yargs.getOptions()` contained the state of the last command to execute.
|
|
45
|
+
* do not allow additional positionals in strict mode
|
|
46
|
+
|
|
47
|
+
### Bug Fixes
|
|
48
|
+
|
|
49
|
+
* calling parse multiple times now appropriately maintains state ([#1137](https://github.com/yargs/yargs/issues/1137)) ([#1369](https://github.com/yargs/yargs/issues/1369)) ([026b151](https://github.com/yargs/yargs/commit/026b151))
|
|
50
|
+
* prefer user supplied script name in usage ([#1383](https://github.com/yargs/yargs/issues/1383)) ([28c74b9](https://github.com/yargs/yargs/commit/28c74b9))
|
|
51
|
+
* **deps:** use decamelize from npm instead of vendored copy ([#1377](https://github.com/yargs/yargs/issues/1377)) ([015eeb9](https://github.com/yargs/yargs/commit/015eeb9))
|
|
52
|
+
* **examples:** fix usage-options.js to reflect current API ([#1375](https://github.com/yargs/yargs/issues/1375)) ([6e5b76b](https://github.com/yargs/yargs/commit/6e5b76b))
|
|
53
|
+
* do not allow additional positionals in strict mode ([35d777c](https://github.com/yargs/yargs/commit/35d777c))
|
|
54
|
+
* properties accessed on singleton now reflect current state of instance ([#1366](https://github.com/yargs/yargs/issues/1366)) ([409d35b](https://github.com/yargs/yargs/commit/409d35b))
|
|
55
|
+
* tolerate null prototype for config objects with `extends` ([#1376](https://github.com/yargs/yargs/issues/1376)) ([3d26d11](https://github.com/yargs/yargs/commit/3d26d11)), closes [#1372](https://github.com/yargs/yargs/issues/1372)
|
|
56
|
+
* yargs.parsed now populated before returning, when yargs.parse() called with no args (#1382) ([e3981fd](https://github.com/yargs/yargs/commit/e3981fd)), closes [#1382](https://github.com/yargs/yargs/issues/1382)
|
|
57
|
+
|
|
58
|
+
### Features
|
|
59
|
+
|
|
60
|
+
* adds support for multiple epilog messages ([#1384](https://github.com/yargs/yargs/issues/1384)) ([07a5554](https://github.com/yargs/yargs/commit/07a5554))
|
|
61
|
+
* allow completionCommand to be set via showCompletionScript ([#1385](https://github.com/yargs/yargs/issues/1385)) ([5562853](https://github.com/yargs/yargs/commit/5562853))
|
|
62
|
+
|
|
5
63
|
## [13.3.0](https://www.github.com/yargs/yargs/compare/v13.2.4...v13.3.0) (2019-06-10)
|
|
6
64
|
|
|
7
65
|
|
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
<p align="center">
|
|
6
6
|
<b >Yargs be a node.js library fer hearties tryin' ter parse optstrings</b>
|
|
7
7
|
</p>
|
|
8
|
+
|
|
8
9
|
<br>
|
|
9
10
|
|
|
10
11
|
[![Build Status][travis-image]][travis-url]
|
|
@@ -15,7 +16,7 @@
|
|
|
15
16
|
[![Slack][slack-image]][slack-url]
|
|
16
17
|
|
|
17
18
|
## Description :
|
|
18
|
-
Yargs helps you build interactive command line tools, by parsing arguments and generating an elegant user interface.
|
|
19
|
+
Yargs helps you build interactive command line tools, by parsing arguments and generating an elegant user interface.
|
|
19
20
|
|
|
20
21
|
It gives you:
|
|
21
22
|
|
|
@@ -79,13 +80,24 @@ require('yargs') // eslint-disable-line
|
|
|
79
80
|
})
|
|
80
81
|
.option('verbose', {
|
|
81
82
|
alias: 'v',
|
|
82
|
-
|
|
83
|
+
type: 'boolean',
|
|
84
|
+
description: 'Run with verbose logging'
|
|
83
85
|
})
|
|
84
86
|
.argv
|
|
85
87
|
```
|
|
86
88
|
|
|
87
89
|
Run the example above with `--help` to see the help for the application.
|
|
88
90
|
|
|
91
|
+
## TypeScript
|
|
92
|
+
|
|
93
|
+
yargs has type definitions at [@types/yargs][type-definitions].
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
npm i @types/yargs --save-dev
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
See usage examples in [docs](/docs/typescript.md).
|
|
100
|
+
|
|
89
101
|
## Community :
|
|
90
102
|
|
|
91
103
|
Having problems? want to contribute? join our [community slack](http://devtoolscommunity.herokuapp.com).
|
|
@@ -102,6 +114,7 @@ Having problems? want to contribute? join our [community slack](http://devtoolsc
|
|
|
102
114
|
* [Numbers](/docs/tricks.md#numbers)
|
|
103
115
|
* [Arrays](/docs/tricks.md#arrays)
|
|
104
116
|
* [Objects](/docs/tricks.md#objects)
|
|
117
|
+
* [Quotes](/docs/tricks.md#quotes)
|
|
105
118
|
* [Advanced Topics](/docs/advanced.md)
|
|
106
119
|
* [Composing Your App Using Commands](/docs/advanced.md#commands)
|
|
107
120
|
* [Building Configurable CLI Apps](/docs/advanced.md#configuration)
|
|
@@ -120,3 +133,4 @@ Having problems? want to contribute? join our [community slack](http://devtoolsc
|
|
|
120
133
|
[conventional-commits-url]: https://conventionalcommits.org/
|
|
121
134
|
[slack-image]: http://devtoolscommunity.herokuapp.com/badge.svg
|
|
122
135
|
[slack-url]: http://devtoolscommunity.herokuapp.com
|
|
136
|
+
[type-definitions]: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/yargs
|
package/index.js
CHANGED
|
@@ -25,8 +25,15 @@ function singletonify (inst) {
|
|
|
25
25
|
Object.keys(inst).forEach((key) => {
|
|
26
26
|
if (key === 'argv') {
|
|
27
27
|
Argv.__defineGetter__(key, inst.__lookupGetter__(key))
|
|
28
|
+
} else if (typeof inst[key] === 'function') {
|
|
29
|
+
Argv[key] = inst[key].bind(inst)
|
|
28
30
|
} else {
|
|
29
|
-
Argv
|
|
31
|
+
Argv.__defineGetter__('$0', () => {
|
|
32
|
+
return inst.$0
|
|
33
|
+
})
|
|
34
|
+
Argv.__defineGetter__('parsed', () => {
|
|
35
|
+
return inst.parsed
|
|
36
|
+
})
|
|
30
37
|
}
|
|
31
38
|
})
|
|
32
39
|
}
|
package/lib/apply-extends.js
CHANGED
|
@@ -16,10 +16,24 @@ function getPathToDefaultConfig (cwd, pathToExtend) {
|
|
|
16
16
|
return path.resolve(cwd, pathToExtend)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
function
|
|
19
|
+
function mergeDeep (config1, config2) {
|
|
20
|
+
const target = {}
|
|
21
|
+
const isObject = obj => obj && typeof obj === 'object' && !Array.isArray(obj)
|
|
22
|
+
Object.assign(target, config1)
|
|
23
|
+
for (let key of Object.keys(config2)) {
|
|
24
|
+
if (isObject(config2[key]) && isObject(target[key])) {
|
|
25
|
+
target[key] = mergeDeep(config1[key], config2[key])
|
|
26
|
+
} else {
|
|
27
|
+
target[key] = config2[key]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return target
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function applyExtends (config, cwd, mergeExtends) {
|
|
20
34
|
let defaultConfig = {}
|
|
21
35
|
|
|
22
|
-
if (
|
|
36
|
+
if (Object.prototype.hasOwnProperty.call(config, 'extends')) {
|
|
23
37
|
if (typeof config.extends !== 'string') return defaultConfig
|
|
24
38
|
const isPath = /\.json|\..*rc$/.test(config.extends)
|
|
25
39
|
let pathToDefault = null
|
|
@@ -42,12 +56,12 @@ function applyExtends (config, cwd) {
|
|
|
42
56
|
|
|
43
57
|
defaultConfig = isPath ? JSON.parse(fs.readFileSync(pathToDefault, 'utf8')) : require(config.extends)
|
|
44
58
|
delete config.extends
|
|
45
|
-
defaultConfig = applyExtends(defaultConfig, path.dirname(pathToDefault))
|
|
59
|
+
defaultConfig = applyExtends(defaultConfig, path.dirname(pathToDefault), mergeExtends)
|
|
46
60
|
}
|
|
47
61
|
|
|
48
62
|
previouslyVisitedConfigs = []
|
|
49
63
|
|
|
50
|
-
return Object.assign({}, defaultConfig, config)
|
|
64
|
+
return mergeExtends ? mergeDeep(defaultConfig, config) : Object.assign({}, defaultConfig, config)
|
|
51
65
|
}
|
|
52
66
|
|
|
53
67
|
module.exports = applyExtends
|
package/lib/command.js
CHANGED
|
@@ -174,7 +174,7 @@ module.exports = function command (yargs, usage, validation, globalMiddleware) {
|
|
|
174
174
|
let numFiles = currentContext.files.length
|
|
175
175
|
const parentCommands = currentContext.commands.slice()
|
|
176
176
|
|
|
177
|
-
// what does yargs look like after the
|
|
177
|
+
// what does yargs look like after the builder is run?
|
|
178
178
|
let innerArgv = parsed.argv
|
|
179
179
|
let innerYargs = null
|
|
180
180
|
let positionalMap = {}
|
|
@@ -186,24 +186,17 @@ module.exports = function command (yargs, usage, validation, globalMiddleware) {
|
|
|
186
186
|
// a function can be provided, which builds
|
|
187
187
|
// up a yargs chain and possibly returns it.
|
|
188
188
|
innerYargs = commandHandler.builder(yargs.reset(parsed.aliases))
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
// original command string as usage() for consistent behavior with
|
|
192
|
-
// options object below.
|
|
193
|
-
if (yargs.parsed === false) {
|
|
194
|
-
if (shouldUpdateUsage(yargs)) {
|
|
195
|
-
yargs.getUsageInstance().usage(
|
|
196
|
-
usageFromParentCommandsCommandHandler(parentCommands, commandHandler),
|
|
197
|
-
commandHandler.description
|
|
198
|
-
)
|
|
199
|
-
}
|
|
200
|
-
innerArgv = innerYargs ? innerYargs._parseArgs(null, null, true, commandIndex) : yargs._parseArgs(null, null, true, commandIndex)
|
|
201
|
-
} else {
|
|
202
|
-
innerArgv = yargs.parsed.argv
|
|
189
|
+
if (!innerYargs || (typeof innerYargs._parseArgs !== 'function')) {
|
|
190
|
+
innerYargs = yargs
|
|
203
191
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
192
|
+
if (shouldUpdateUsage(innerYargs)) {
|
|
193
|
+
innerYargs.getUsageInstance().usage(
|
|
194
|
+
usageFromParentCommandsCommandHandler(parentCommands, commandHandler),
|
|
195
|
+
commandHandler.description
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
innerArgv = innerYargs._parseArgs(null, null, true, commandIndex)
|
|
199
|
+
aliases = innerYargs.parsed.aliases
|
|
207
200
|
} else if (typeof commandHandler.builder === 'object') {
|
|
208
201
|
// as a short hand, an object can instead be provided, specifying
|
|
209
202
|
// the options that a command takes.
|
|
@@ -237,14 +230,22 @@ module.exports = function command (yargs, usage, validation, globalMiddleware) {
|
|
|
237
230
|
|
|
238
231
|
innerArgv = applyMiddleware(innerArgv, yargs, middlewares, false)
|
|
239
232
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
233
|
+
let handlerResult
|
|
234
|
+
if (isPromise(innerArgv)) {
|
|
235
|
+
handlerResult = innerArgv.then(argv => commandHandler.handler(argv))
|
|
236
|
+
} else {
|
|
237
|
+
handlerResult = commandHandler.handler(innerArgv)
|
|
238
|
+
}
|
|
243
239
|
|
|
244
240
|
if (isPromise(handlerResult)) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
241
|
+
yargs.getUsageInstance().cacheHelpMessage()
|
|
242
|
+
handlerResult.catch(error => {
|
|
243
|
+
try {
|
|
244
|
+
yargs.getUsageInstance().fail(null, error)
|
|
245
|
+
} catch (err) {
|
|
246
|
+
// fail's throwing would cause an unhandled rejection.
|
|
247
|
+
}
|
|
248
|
+
})
|
|
248
249
|
}
|
|
249
250
|
}
|
|
250
251
|
|
|
@@ -419,18 +420,19 @@ module.exports = function command (yargs, usage, validation, globalMiddleware) {
|
|
|
419
420
|
// the state of commands such that
|
|
420
421
|
// we can apply .parse() multiple times
|
|
421
422
|
// with the same yargs instance.
|
|
422
|
-
let
|
|
423
|
+
let frozens = []
|
|
423
424
|
self.freeze = () => {
|
|
424
|
-
frozen = {}
|
|
425
|
+
let frozen = {}
|
|
426
|
+
frozens.push(frozen)
|
|
425
427
|
frozen.handlers = handlers
|
|
426
428
|
frozen.aliasMap = aliasMap
|
|
427
429
|
frozen.defaultCommand = defaultCommand
|
|
428
430
|
}
|
|
429
431
|
self.unfreeze = () => {
|
|
432
|
+
let frozen = frozens.pop()
|
|
430
433
|
handlers = frozen.handlers
|
|
431
434
|
aliasMap = frozen.aliasMap
|
|
432
435
|
defaultCommand = frozen.defaultCommand
|
|
433
|
-
frozen = undefined
|
|
434
436
|
}
|
|
435
437
|
|
|
436
438
|
return self
|
package/lib/completion.js
CHANGED
|
@@ -8,7 +8,8 @@ module.exports = function completion (yargs, usage, command) {
|
|
|
8
8
|
completionKey: 'get-yargs-completions'
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
const zshShell = process.env.SHELL && process.env.SHELL.indexOf('zsh') !== -1
|
|
11
|
+
const zshShell = (process.env.SHELL && process.env.SHELL.indexOf('zsh') !== -1) ||
|
|
12
|
+
(process.env.ZSH_NAME && process.env.ZSH_NAME.indexOf('zsh') !== -1)
|
|
12
13
|
// get a list of completion commands.
|
|
13
14
|
// 'args' is the array of strings from the line to be completed
|
|
14
15
|
self.getCompletion = function getCompletion (args, done) {
|
package/lib/is-promise.js
CHANGED
package/lib/middleware.js
CHANGED
|
@@ -40,8 +40,7 @@ function applyMiddleware (argv, yargs, middlewares, beforeValidation) {
|
|
|
40
40
|
const beforeValidationError = new Error('middleware cannot return a promise when applyBeforeValidation is true')
|
|
41
41
|
return middlewares
|
|
42
42
|
.reduce((accumulation, middleware) => {
|
|
43
|
-
if (middleware.applyBeforeValidation !== beforeValidation
|
|
44
|
-
!isPromise(accumulation)) {
|
|
43
|
+
if (middleware.applyBeforeValidation !== beforeValidation) {
|
|
45
44
|
return accumulation
|
|
46
45
|
}
|
|
47
46
|
|
package/lib/usage.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
// this file handles outputting usage instructions,
|
|
3
3
|
// failures, etc. keeps logging in one place.
|
|
4
|
-
const decamelize = require('
|
|
4
|
+
const decamelize = require('decamelize')
|
|
5
5
|
const stringWidth = require('string-width')
|
|
6
6
|
const objFilter = require('./obj-filter')
|
|
7
7
|
const path = require('path')
|
|
@@ -122,9 +122,9 @@ module.exports = function usage (yargs, y18n) {
|
|
|
122
122
|
}
|
|
123
123
|
self.getDescriptions = () => descriptions
|
|
124
124
|
|
|
125
|
-
let
|
|
125
|
+
let epilogs = []
|
|
126
126
|
self.epilog = (msg) => {
|
|
127
|
-
|
|
127
|
+
epilogs.push(msg)
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
let wrapSet = false
|
|
@@ -148,10 +148,11 @@ module.exports = function usage (yargs, y18n) {
|
|
|
148
148
|
|
|
149
149
|
const defaultGroup = 'Options:'
|
|
150
150
|
self.help = function help () {
|
|
151
|
+
if (cachedHelpMessage) return cachedHelpMessage
|
|
151
152
|
normalizeAliases()
|
|
152
153
|
|
|
153
154
|
// handle old demanded API
|
|
154
|
-
const base$0 = path.basename(yargs.$0)
|
|
155
|
+
const base$0 = yargs.customScriptName ? yargs.$0 : path.basename(yargs.$0)
|
|
155
156
|
const demandedOptions = yargs.getDemandedOptions()
|
|
156
157
|
const demandedCommands = yargs.getDemandedCommands()
|
|
157
158
|
const groups = yargs.getGroups()
|
|
@@ -345,8 +346,8 @@ module.exports = function usage (yargs, y18n) {
|
|
|
345
346
|
}
|
|
346
347
|
|
|
347
348
|
// the usage string.
|
|
348
|
-
if (
|
|
349
|
-
const e = epilog.replace(/\$0/g, base$0)
|
|
349
|
+
if (epilogs.length > 0) {
|
|
350
|
+
const e = epilogs.map(epilog => epilog.replace(/\$0/g, base$0)).join('\n')
|
|
350
351
|
ui.div(`${e}\n`)
|
|
351
352
|
}
|
|
352
353
|
|
|
@@ -403,6 +404,13 @@ module.exports = function usage (yargs, y18n) {
|
|
|
403
404
|
})
|
|
404
405
|
}
|
|
405
406
|
|
|
407
|
+
// if yargs is executing an async handler, we take a snapshot of the
|
|
408
|
+
// help message to display on failure:
|
|
409
|
+
let cachedHelpMessage
|
|
410
|
+
self.cacheHelpMessage = function () {
|
|
411
|
+
cachedHelpMessage = this.help()
|
|
412
|
+
}
|
|
413
|
+
|
|
406
414
|
// given a set of keys, place any keys that are
|
|
407
415
|
// ungrouped under the 'Options:' grouping.
|
|
408
416
|
function addUngroupedKeys (keys, aliases, groups) {
|
|
@@ -505,35 +513,36 @@ module.exports = function usage (yargs, y18n) {
|
|
|
505
513
|
failureOutput = false
|
|
506
514
|
usages = []
|
|
507
515
|
usageDisabled = false
|
|
508
|
-
|
|
516
|
+
epilogs = []
|
|
509
517
|
examples = []
|
|
510
518
|
commands = []
|
|
511
519
|
descriptions = objFilter(descriptions, (k, v) => !localLookup[k])
|
|
512
520
|
return self
|
|
513
521
|
}
|
|
514
522
|
|
|
515
|
-
let
|
|
523
|
+
let frozens = []
|
|
516
524
|
self.freeze = function freeze () {
|
|
517
|
-
frozen = {}
|
|
525
|
+
let frozen = {}
|
|
526
|
+
frozens.push(frozen)
|
|
518
527
|
frozen.failMessage = failMessage
|
|
519
528
|
frozen.failureOutput = failureOutput
|
|
520
529
|
frozen.usages = usages
|
|
521
530
|
frozen.usageDisabled = usageDisabled
|
|
522
|
-
frozen.
|
|
531
|
+
frozen.epilogs = epilogs
|
|
523
532
|
frozen.examples = examples
|
|
524
533
|
frozen.commands = commands
|
|
525
534
|
frozen.descriptions = descriptions
|
|
526
535
|
}
|
|
527
536
|
self.unfreeze = function unfreeze () {
|
|
537
|
+
let frozen = frozens.pop()
|
|
528
538
|
failMessage = frozen.failMessage
|
|
529
539
|
failureOutput = frozen.failureOutput
|
|
530
540
|
usages = frozen.usages
|
|
531
541
|
usageDisabled = frozen.usageDisabled
|
|
532
|
-
|
|
542
|
+
epilogs = frozen.epilogs
|
|
533
543
|
examples = frozen.examples
|
|
534
544
|
commands = frozen.commands
|
|
535
545
|
descriptions = frozen.descriptions
|
|
536
|
-
frozen = undefined
|
|
537
546
|
}
|
|
538
547
|
|
|
539
548
|
return self
|
package/lib/validation.js
CHANGED
|
@@ -96,13 +96,13 @@ module.exports = function validation (yargs, usage, y18n) {
|
|
|
96
96
|
if (specialKeys.indexOf(key) === -1 &&
|
|
97
97
|
!positionalMap.hasOwnProperty(key) &&
|
|
98
98
|
!yargs._getParseContext().hasOwnProperty(key) &&
|
|
99
|
-
!
|
|
99
|
+
!self.isValidAndSomeAliasIsNotNew(key, aliases)
|
|
100
100
|
) {
|
|
101
101
|
unknown.push(key)
|
|
102
102
|
}
|
|
103
103
|
})
|
|
104
104
|
|
|
105
|
-
if (commandKeys.length > 0) {
|
|
105
|
+
if ((currentContext.commands.length > 0) || (commandKeys.length > 0)) {
|
|
106
106
|
argv._.slice(currentContext.commands.length).forEach((key) => {
|
|
107
107
|
if (commandKeys.indexOf(key) === -1) {
|
|
108
108
|
unknown.push(key)
|
|
@@ -120,6 +120,21 @@ module.exports = function validation (yargs, usage, y18n) {
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
// check for a key that is not an alias, or for which every alias is new,
|
|
124
|
+
// implying that it was invented by the parser, e.g., during camelization
|
|
125
|
+
self.isValidAndSomeAliasIsNotNew = function isValidAndSomeAliasIsNotNew (key, aliases) {
|
|
126
|
+
if (!aliases.hasOwnProperty(key)) {
|
|
127
|
+
return false
|
|
128
|
+
}
|
|
129
|
+
const newAliases = yargs.parsed.newAliases
|
|
130
|
+
for (let a of [key, ...aliases[key]]) {
|
|
131
|
+
if (!newAliases.hasOwnProperty(a) || !newAliases[key]) {
|
|
132
|
+
return true
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return false
|
|
136
|
+
}
|
|
137
|
+
|
|
123
138
|
// validate arguments limited to enumerated choices
|
|
124
139
|
self.limitedChoices = function limitedChoices (argv) {
|
|
125
140
|
const options = yargs.getOptions()
|
|
@@ -209,43 +224,36 @@ module.exports = function validation (yargs, usage, y18n) {
|
|
|
209
224
|
return implied
|
|
210
225
|
}
|
|
211
226
|
|
|
227
|
+
function keyExists (argv, val) {
|
|
228
|
+
// convert string '1' to number 1
|
|
229
|
+
let num = Number(val)
|
|
230
|
+
val = isNaN(num) ? val : num
|
|
231
|
+
|
|
232
|
+
if (typeof val === 'number') {
|
|
233
|
+
// check length of argv._
|
|
234
|
+
val = argv._.length >= val
|
|
235
|
+
} else if (val.match(/^--no-.+/)) {
|
|
236
|
+
// check if key/value doesn't exist
|
|
237
|
+
val = val.match(/^--no-(.+)/)[1]
|
|
238
|
+
val = !argv[val]
|
|
239
|
+
} else {
|
|
240
|
+
// check if key/value exists
|
|
241
|
+
val = argv[val]
|
|
242
|
+
}
|
|
243
|
+
return val
|
|
244
|
+
}
|
|
245
|
+
|
|
212
246
|
self.implications = function implications (argv) {
|
|
213
247
|
const implyFail = []
|
|
214
248
|
|
|
215
249
|
Object.keys(implied).forEach((key) => {
|
|
216
250
|
const origKey = key
|
|
217
251
|
;(implied[key] || []).forEach((value) => {
|
|
218
|
-
let num
|
|
219
252
|
let key = origKey
|
|
220
253
|
const origValue = value
|
|
254
|
+
key = keyExists(argv, key)
|
|
255
|
+
value = keyExists(argv, value)
|
|
221
256
|
|
|
222
|
-
// convert string '1' to number 1
|
|
223
|
-
num = Number(key)
|
|
224
|
-
key = isNaN(num) ? key : num
|
|
225
|
-
|
|
226
|
-
if (typeof key === 'number') {
|
|
227
|
-
// check length of argv._
|
|
228
|
-
key = argv._.length >= key
|
|
229
|
-
} else if (key.match(/^--no-.+/)) {
|
|
230
|
-
// check if key doesn't exist
|
|
231
|
-
key = key.match(/^--no-(.+)/)[1]
|
|
232
|
-
key = !argv[key]
|
|
233
|
-
} else {
|
|
234
|
-
// check if key exists
|
|
235
|
-
key = argv[key]
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
num = Number(value)
|
|
239
|
-
value = isNaN(num) ? value : num
|
|
240
|
-
|
|
241
|
-
if (typeof value === 'number') {
|
|
242
|
-
value = argv._.length >= value
|
|
243
|
-
} else if (value.match(/^--no-.+/)) {
|
|
244
|
-
value = value.match(/^--no-(.+)/)[1]
|
|
245
|
-
value = !argv[value]
|
|
246
|
-
} else {
|
|
247
|
-
value = argv[value]
|
|
248
|
-
}
|
|
249
257
|
if (key && !value) {
|
|
250
258
|
implyFail.push(` ${origKey} -> ${origValue}`)
|
|
251
259
|
}
|
|
@@ -323,18 +331,19 @@ module.exports = function validation (yargs, usage, y18n) {
|
|
|
323
331
|
return self
|
|
324
332
|
}
|
|
325
333
|
|
|
326
|
-
let
|
|
334
|
+
let frozens = []
|
|
327
335
|
self.freeze = function freeze () {
|
|
328
|
-
frozen = {}
|
|
336
|
+
let frozen = {}
|
|
337
|
+
frozens.push(frozen)
|
|
329
338
|
frozen.implied = implied
|
|
330
339
|
frozen.checks = checks
|
|
331
340
|
frozen.conflicting = conflicting
|
|
332
341
|
}
|
|
333
342
|
self.unfreeze = function unfreeze () {
|
|
343
|
+
let frozen = frozens.pop()
|
|
334
344
|
implied = frozen.implied
|
|
335
345
|
checks = frozen.checks
|
|
336
346
|
conflicting = frozen.conflicting
|
|
337
|
-
frozen = undefined
|
|
338
347
|
}
|
|
339
348
|
|
|
340
349
|
return self
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yargs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.2.0",
|
|
4
4
|
"description": "yargs the modern, pirate-themed, successor to optimist.",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"contributors": [
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"cliui": "^5.0.0",
|
|
23
|
+
"decamelize": "^1.2.0",
|
|
23
24
|
"find-up": "^3.0.0",
|
|
24
25
|
"get-caller-file": "^2.0.1",
|
|
25
26
|
"require-directory": "^2.1.1",
|
|
@@ -28,7 +29,7 @@
|
|
|
28
29
|
"string-width": "^3.0.0",
|
|
29
30
|
"which-module": "^2.0.0",
|
|
30
31
|
"y18n": "^4.0.0",
|
|
31
|
-
"yargs-parser": "^
|
|
32
|
+
"yargs-parser": "^15.0.0"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"chai": "^4.2.0",
|
|
@@ -42,7 +43,7 @@
|
|
|
42
43
|
"nyc": "^14.1.0",
|
|
43
44
|
"rimraf": "^2.6.3",
|
|
44
45
|
"standard": "^12.0.1",
|
|
45
|
-
"standard-version": "^
|
|
46
|
+
"standard-version": "^7.0.0",
|
|
46
47
|
"which": "^1.3.1",
|
|
47
48
|
"yargs-test-extends": "^1.0.1"
|
|
48
49
|
},
|
package/yargs.js
CHANGED
|
@@ -37,7 +37,8 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
37
37
|
|
|
38
38
|
if (!cwd) cwd = process.cwd()
|
|
39
39
|
|
|
40
|
-
self.scriptName = function
|
|
40
|
+
self.scriptName = function (scriptName) {
|
|
41
|
+
self.customScriptName = true
|
|
41
42
|
self.$0 = scriptName
|
|
42
43
|
return self
|
|
43
44
|
}
|
|
@@ -93,14 +94,17 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
93
94
|
})
|
|
94
95
|
})
|
|
95
96
|
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
// add all groups not set to local to preserved groups
|
|
98
|
+
Object.assign(
|
|
99
|
+
preservedGroups,
|
|
100
|
+
Object.keys(groups).reduce((acc, groupName) => {
|
|
101
|
+
const keys = groups[groupName].filter(key => !(key in localLookup))
|
|
102
|
+
if (keys.length > 0) {
|
|
103
|
+
acc[groupName] = keys
|
|
104
|
+
}
|
|
105
|
+
return acc
|
|
106
|
+
}, {})
|
|
107
|
+
)
|
|
104
108
|
// groups can now be reset
|
|
105
109
|
groups = {}
|
|
106
110
|
|
|
@@ -144,9 +148,10 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
144
148
|
self.resetOptions()
|
|
145
149
|
|
|
146
150
|
// temporary hack: allow "freezing" of reset-able state for parse(msg, cb)
|
|
147
|
-
let
|
|
151
|
+
let frozens = []
|
|
148
152
|
function freeze () {
|
|
149
|
-
frozen = {}
|
|
153
|
+
let frozen = {}
|
|
154
|
+
frozens.push(frozen)
|
|
150
155
|
frozen.options = options
|
|
151
156
|
frozen.configObjects = options.configObjects.slice(0)
|
|
152
157
|
frozen.exitProcess = exitProcess
|
|
@@ -160,8 +165,11 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
160
165
|
frozen.exitError = exitError
|
|
161
166
|
frozen.hasOutput = hasOutput
|
|
162
167
|
frozen.parsed = self.parsed
|
|
168
|
+
frozen.parseFn = parseFn
|
|
169
|
+
frozen.parseContext = parseContext
|
|
163
170
|
}
|
|
164
171
|
function unfreeze () {
|
|
172
|
+
let frozen = frozens.pop()
|
|
165
173
|
options = frozen.options
|
|
166
174
|
options.configObjects = frozen.configObjects
|
|
167
175
|
exitProcess = frozen.exitProcess
|
|
@@ -175,9 +183,8 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
175
183
|
command.unfreeze()
|
|
176
184
|
strict = frozen.strict
|
|
177
185
|
completionCommand = frozen.completionCommand
|
|
178
|
-
parseFn =
|
|
179
|
-
parseContext =
|
|
180
|
-
frozen = undefined
|
|
186
|
+
parseFn = frozen.parseFn
|
|
187
|
+
parseContext = frozen.parseContext
|
|
181
188
|
}
|
|
182
189
|
|
|
183
190
|
self.boolean = function (keys) {
|
|
@@ -326,7 +333,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
326
333
|
argsert('[object|string] [string|function] [function]', [key, msg, parseFn], arguments.length)
|
|
327
334
|
// allow a config object to be provided directly.
|
|
328
335
|
if (typeof key === 'object') {
|
|
329
|
-
key = applyExtends(key, cwd)
|
|
336
|
+
key = applyExtends(key, cwd, self.getParserConfiguration()['deep-merge-config'])
|
|
330
337
|
options.configObjects = (options.configObjects || []).concat(key)
|
|
331
338
|
return self
|
|
332
339
|
}
|
|
@@ -500,7 +507,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
500
507
|
|
|
501
508
|
// If an object exists in the key, add it to options.configObjects
|
|
502
509
|
if (obj[key] && typeof obj[key] === 'object') {
|
|
503
|
-
conf = applyExtends(obj[key], rootPath || cwd)
|
|
510
|
+
conf = applyExtends(obj[key], rootPath || cwd, self.getParserConfiguration()['deep-merge-config'])
|
|
504
511
|
options.configObjects = (options.configObjects || []).concat(conf)
|
|
505
512
|
}
|
|
506
513
|
|
|
@@ -538,8 +545,14 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
538
545
|
let parseContext = null
|
|
539
546
|
self.parse = function parse (args, shortCircuit, _parseFn) {
|
|
540
547
|
argsert('[string|array] [function|boolean|object] [function]', [args, shortCircuit, _parseFn], arguments.length)
|
|
548
|
+
freeze()
|
|
541
549
|
if (typeof args === 'undefined') {
|
|
542
|
-
|
|
550
|
+
const argv = self._parseArgs(processArgs)
|
|
551
|
+
const tmpParsed = self.parsed
|
|
552
|
+
unfreeze()
|
|
553
|
+
// TODO: remove this compatibility hack when we release yargs@15.x:
|
|
554
|
+
self.parsed = tmpParsed
|
|
555
|
+
return argv
|
|
543
556
|
}
|
|
544
557
|
|
|
545
558
|
// a context object can optionally be provided, this allows
|
|
@@ -560,7 +573,6 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
560
573
|
// skipping validation, etc.
|
|
561
574
|
if (!shortCircuit) processArgs = args
|
|
562
575
|
|
|
563
|
-
freeze()
|
|
564
576
|
if (parseFn) exitProcess = false
|
|
565
577
|
|
|
566
578
|
const parsed = self._parseArgs(args, shortCircuit)
|
|
@@ -901,7 +913,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
901
913
|
}
|
|
902
914
|
|
|
903
915
|
// register the completion command.
|
|
904
|
-
completionCommand = cmd || 'completion'
|
|
916
|
+
completionCommand = cmd || completionCommand || 'completion'
|
|
905
917
|
if (!desc && desc !== false) {
|
|
906
918
|
desc = 'generate completion script'
|
|
907
919
|
}
|
|
@@ -913,10 +925,10 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
913
925
|
return self
|
|
914
926
|
}
|
|
915
927
|
|
|
916
|
-
self.showCompletionScript = function ($0) {
|
|
917
|
-
argsert('[string]', [$0], arguments.length)
|
|
928
|
+
self.showCompletionScript = function ($0, cmd) {
|
|
929
|
+
argsert('[string] [string]', [$0, cmd], arguments.length)
|
|
918
930
|
$0 = $0 || self.$0
|
|
919
|
-
_logger.log(completion.generateCompletionScript($0, completionCommand))
|
|
931
|
+
_logger.log(completion.generateCompletionScript($0, cmd || completionCommand || 'completion'))
|
|
920
932
|
return self
|
|
921
933
|
}
|
|
922
934
|
|
|
@@ -1023,7 +1035,7 @@ function Yargs (processArgs, cwd, parentRequire) {
|
|
|
1023
1035
|
// Deprecated
|
|
1024
1036
|
let pkgConfig = pkgUp()['yargs']
|
|
1025
1037
|
if (pkgConfig) {
|
|
1026
|
-
console.warn('Configuring yargs through package.json is deprecated and will be removed in
|
|
1038
|
+
console.warn('Configuring yargs through package.json is deprecated and will be removed in a future major release, please use the JS API instead.')
|
|
1027
1039
|
options.configuration = Object.assign({}, pkgConfig, options.configuration)
|
|
1028
1040
|
}
|
|
1029
1041
|
|
package/lib/decamelize.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
MIT License
|
|
3
|
-
|
|
4
|
-
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
|
5
|
-
|
|
6
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
7
|
-
this software and associated documentation files (the "Software"), to deal in
|
|
8
|
-
the Software without restriction, including without limitation the rights to
|
|
9
|
-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
10
|
-
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
11
|
-
subject to the following conditions:
|
|
12
|
-
|
|
13
|
-
The above copyright notice and this permission notice shall be included in all
|
|
14
|
-
copies or substantial portions of the Software.
|
|
15
|
-
|
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
18
|
-
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
19
|
-
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
20
|
-
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
21
|
-
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
-
*/
|
|
23
|
-
'use strict'
|
|
24
|
-
|
|
25
|
-
module.exports = (text, separator) => {
|
|
26
|
-
separator = typeof separator === 'undefined' ? '_' : separator
|
|
27
|
-
|
|
28
|
-
return text
|
|
29
|
-
.replace(/([a-z\d])([A-Z])/g, `$1${separator}$2`)
|
|
30
|
-
.replace(/([A-Z]+)([A-Z][a-z\d]+)/g, `$1${separator}$2`)
|
|
31
|
-
.toLowerCase()
|
|
32
|
-
}
|