Skip to content

Commit

Permalink
feat: deprecateOption (#1559)
Browse files Browse the repository at this point in the history
  • Loading branch information
laggingreflex committed Feb 22, 2020
1 parent ecfc2c4 commit 8aae333
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 2 deletions.
38 changes: 38 additions & 0 deletions docs/api.md
Expand Up @@ -578,6 +578,44 @@ _Note: in `minMsg` and `maxMsg`, every occurrence of `$0` will be replaced
with the observed value, and every instance of `$1` will be replaced with the
expected value._

<a name="deprecateOption"></a>.deprecateOption(key, [msg | boolean])
--------------------

Shows a `[deprecated]` notice in front of the option.

```javascript
require('yargs')
.option('old')
.deprecateOption('old')
.option('new')
```
```bash
Options:
--old [deprecated]
--new
```

You can also specify a message

```javascript
require('yargs')
.option('old')
.deprecateOption('old', 'use --new')
.option('new')
```
```bash
Options:
--old [deprecated: use --new]
--new
```

You can also use it within the option constructor

```javascript
require('yargs')
.option('old', { deprecated: true })
```

<a name="describe"></a>.describe(key, desc)
--------------------

Expand Down
6 changes: 6 additions & 0 deletions lib/usage.js
Expand Up @@ -155,6 +155,7 @@ module.exports = function usage (yargs, y18n) {
const base$0 = yargs.customScriptName ? yargs.$0 : path.basename(yargs.$0)
const demandedOptions = yargs.getDemandedOptions()
const demandedCommands = yargs.getDemandedCommands()
const deprecatedOptions = yargs.getDeprecatedOptions()
const groups = yargs.getGroups()
const options = yargs.getOptions()

Expand Down Expand Up @@ -294,6 +295,11 @@ module.exports = function usage (yargs, y18n) {
if (~options.number.indexOf(key)) type = `[${__('number')}]`

const extra = [
(key in deprecatedOptions) ? (
typeof deprecatedOptions[key] === 'string'
? `[${__('deprecated: %s', deprecatedOptions[key])}]`
: `[${__('deprecated')}]`
) : null,
type,
(key in demandedOptions) ? `[${__('required')}]` : null,
options.choices && options.choices[key] ? `[${__('choices:')} ${
Expand Down
4 changes: 3 additions & 1 deletion locales/en.json
Expand Up @@ -45,5 +45,7 @@
"Did you mean %s?": "Did you mean %s?",
"Arguments %s and %s are mutually exclusive" : "Arguments %s and %s are mutually exclusive",
"Positionals:": "Positionals:",
"command": "command"
"command": "command",
"deprecated": "deprecated",
"deprecated: %s": "deprecated: %s"
}
83 changes: 83 additions & 0 deletions test/usage.js
Expand Up @@ -313,6 +313,89 @@ describe('usage tests', () => {
})
})

describe('deprecate options', () => {
describe('using .option(x, {deprecate: [boolean|string]})', () => {
it('{deprecated: true} should show [deprecated]', () => {
const r = checkUsage(() => yargs('--help')
.option('x', { deprecated: true })
.wrap(null)
.parse()
)
r.logs[0].should.include(' -x [deprecated]')
})
it('{deprecated: string} should show [deprecated: string]', () => {
const r = checkUsage(() => yargs('--help')
.option('x', { deprecated: 'string' })
.wrap(null)
.parse()
)
r.logs[0].should.include(' -x [deprecated: string]')
})
it('{deprecated: boolean} in sub-command', () => {
const r = checkUsage(() => yargs('command --help')
.option('x', { deprecated: true })
.command('command', 'command', yargs => yargs.option('y', { deprecated: true }))
.wrap(null)
.parse()
)
r.logs[0].should.include(' -x [deprecated]')
r.logs[0].should.include(' -y [deprecated]')
})
it('{deprecated: string} in sub-command', () => {
const r = checkUsage(() => yargs('command --help')
.option('x', { deprecated: 'string' })
.command('command', 'command', yargs => yargs.option('y', { deprecated: 'string' }))
.wrap(null)
.parse()
)
r.logs[0].should.include(' -x [deprecated: string]')
r.logs[0].should.include(' -y [deprecated: string]')
})
})
describe('using .deprecateOption(x, [string])', () => {
it('.deprecateOption(x) should show [deprecated]', () => {
const r = checkUsage(() => yargs('--help')
.option('x')
.deprecateOption('x')
.wrap(null)
.parse()
)
r.logs[0].should.include(' -x [deprecated]')
})
it('.deprecateOption(x, string) should show [deprecated: string]', () => {
const r = checkUsage(() => yargs('--help')
.option('x')
.deprecateOption('x', 'string')
.wrap(null)
.parse()
)
r.logs[0].should.include(' -x [deprecated: string]')
})
it('.deprecateOption(x) in a sub-command', () => {
const r = checkUsage(() => yargs('command --help')
.option('x')
.deprecateOption('x')
.command('command', 'command', yargs => yargs.option('y').deprecateOption('y'))
.wrap(null)
.parse()
)
r.logs[0].should.include(' -x [deprecated]')
r.logs[0].should.include(' -y [deprecated]')
})
it('.deprecateOption(x, string) in a sub-command', () => {
const r = checkUsage(() => yargs('command --help')
.option('x')
.deprecateOption('x', 'string')
.command('command', 'command', yargs => yargs.option('y').deprecateOption('y', 'string'))
.wrap(null)
.parse()
)
r.logs[0].should.include(' -x [deprecated: string]')
r.logs[0].should.include(' -y [deprecated: string]')
})
})
})

it('should return valid values when check passes', () => {
const r = checkUsage(() => yargs('-x 10 -y 20')
.usage('Usage: $0 -x NUM -y NUM')
Expand Down
1 change: 1 addition & 0 deletions test/yargs.js
Expand Up @@ -322,6 +322,7 @@ describe('yargs dsl tests', () => {
hiddenOptions: [],
demandedCommands: {},
demandedOptions: {},
deprecatedOptions: {},
local: [
'_',
'foo',
Expand Down
20 changes: 19 additions & 1 deletion yargs.js
Expand Up @@ -123,7 +123,8 @@ function Yargs (processArgs, cwd, parentRequire) {

const objectOptions = [
'narg', 'key', 'alias', 'default', 'defaultDescription',
'config', 'choices', 'demandedOptions', 'demandedCommands', 'coerce'
'config', 'choices', 'demandedOptions', 'demandedCommands', 'coerce',
'deprecatedOptions'
]

arrayOptions.forEach((k) => {
Expand Down Expand Up @@ -448,6 +449,17 @@ function Yargs (processArgs, cwd, parentRequire) {
return options.demandedCommands
}

self.deprecateOption = function deprecateOption (option, message) {
argsert('<string> [string|boolean]', [option, message], arguments.length)
options.deprecatedOptions[option] = message
return self
}

self.getDeprecatedOptions = () => {
argsert([], 0)
return options.deprecatedOptions
}

self.implies = function (key, value) {
argsert('<string|object> [number|string|array]', [key, value], arguments.length)
validation.implies(key, value)
Expand Down Expand Up @@ -621,6 +633,12 @@ function Yargs (processArgs, cwd, parentRequire) {

if (opt.alias) self.alias(key, opt.alias)

const deprecate = opt.deprecate || opt.deprecated

if (deprecate) {
self.deprecateOption(key, deprecate)
}

const demand = opt.demand || opt.required || opt.require

// A required option can be specified via "demand: true".
Expand Down

0 comments on commit 8aae333

Please sign in to comment.