From 3ef37c8a8588cfb8a38dde12b2384a47e6956de9 Mon Sep 17 00:00:00 2001 From: laggingreflex Date: Thu, 13 Feb 2020 00:12:16 +0530 Subject: [PATCH 1/3] Shows a `[deprecated]` notice in front of an option * Added a method: `.deprecateOption(key, [message])` * Added a key in option conrtructor: `.option(key, { deprecated: [boolean|message] })` * Basic Tests * Updated Readme --- docs/api.md | 38 ++++++++++++++++++++++++++++++++++++++ lib/usage.js | 4 ++++ test/usage.js | 41 +++++++++++++++++++++++++++++++++++++++++ test/yargs.js | 1 + yargs.js | 20 +++++++++++++++++++- 5 files changed, 103 insertions(+), 1 deletion(-) diff --git a/docs/api.md b/docs/api.md index e6659dd79..26c23d98d 100644 --- a/docs/api.md +++ b/docs/api.md @@ -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._ +.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 }) +``` + .describe(key, desc) -------------------- diff --git a/lib/usage.js b/lib/usage.js index 2aeb7c7ea..deb11e685 100644 --- a/lib/usage.js +++ b/lib/usage.js @@ -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() @@ -294,6 +295,9 @@ module.exports = function usage (yargs, y18n) { if (~options.number.indexOf(key)) type = `[${__('number')}]` const extra = [ + (key in deprecatedOptions) + ? `[${__('deprecated')}${typeof deprecatedOptions[key] === 'string' + ? `: ${deprecatedOptions[key]}` : ''}]` : null, type, (key in demandedOptions) ? `[${__('required')}]` : null, options.choices && options.choices[key] ? `[${__('choices:')} ${ diff --git a/test/usage.js b/test/usage.js index d5408e96b..603ddae62 100644 --- a/test/usage.js +++ b/test/usage.js @@ -313,6 +313,47 @@ 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]') + }) + }) + 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('should return valid values when check passes', () => { const r = checkUsage(() => yargs('-x 10 -y 20') .usage('Usage: $0 -x NUM -y NUM') diff --git a/test/yargs.js b/test/yargs.js index 1ecea4c83..09bc533cc 100644 --- a/test/yargs.js +++ b/test/yargs.js @@ -301,6 +301,7 @@ describe('yargs dsl tests', () => { hiddenOptions: [], demandedCommands: {}, demandedOptions: {}, + deprecatedOptions: {}, local: [ '_', 'foo', diff --git a/yargs.js b/yargs.js index d9a30ac5b..b4009410d 100644 --- a/yargs.js +++ b/yargs.js @@ -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) => { @@ -446,6 +447,17 @@ function Yargs (processArgs, cwd, parentRequire) { return options.demandedCommands } + self.deprecateOption = function deprecateOption (option, message) { + argsert(' [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(' [number|string|array]', [key, value], arguments.length) validation.implies(key, value) @@ -619,6 +631,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". From d285bf82cb5f1fb7992a1359f30b2cd5996506f0 Mon Sep 17 00:00:00 2001 From: laggingreflex Date: Fri, 21 Feb 2020 00:47:03 +0530 Subject: [PATCH 2/3] fix: "deprecated" translation --- lib/usage.js | 8 +++++--- locales/en.json | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/usage.js b/lib/usage.js index a85f97c4c..fb41a3173 100644 --- a/lib/usage.js +++ b/lib/usage.js @@ -295,9 +295,11 @@ module.exports = function usage (yargs, y18n) { if (~options.number.indexOf(key)) type = `[${__('number')}]` const extra = [ - (key in deprecatedOptions) - ? `[${__('deprecated')}${typeof deprecatedOptions[key] === 'string' - ? `: ${deprecatedOptions[key]}` : ''}]` : null, + (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:')} ${ diff --git a/locales/en.json b/locales/en.json index a03c1388b..c2d506bb4 100644 --- a/locales/en.json +++ b/locales/en.json @@ -44,5 +44,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" } From c7d421e48f4ac119d1ee6cd229c4ed04957ce485 Mon Sep 17 00:00:00 2001 From: laggingreflex Date: Sat, 22 Feb 2020 03:44:32 +0530 Subject: [PATCH 3/3] test: add tests for deprecateOption on sub-commands --- test/usage.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/test/usage.js b/test/usage.js index 49a65104e..1d0f3f233 100644 --- a/test/usage.js +++ b/test/usage.js @@ -331,6 +331,26 @@ describe('usage tests', () => { ) 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]', () => { @@ -351,6 +371,28 @@ describe('usage tests', () => { ) 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]') + }) }) })