diff --git a/docs/api.md b/docs/api.md index 193056bc3..afd779d81 100644 --- a/docs/api.md +++ b/docs/api.md @@ -576,6 +576,11 @@ Describe a `key` for the generated usage information. Optionally `.describe()` can take an object that maps keys to descriptions. +.hide(key) +-------------------- + +Hides a `key` from the generated usage information. Unless a `--show-hidden` option is also passed with `--help` (see [`showHidden()`](#showHidden)). + .detectLocale(boolean) ----------- @@ -798,6 +803,29 @@ var yargs = require("yargs")(['--info']) .argv ``` +.showHidden() +----------------------------------------- +.showHidden([option | boolean]) +----------------------------------------- +.showHidden([option, [description]]) +----------------------------------------- + +Configure the `--show-hidden` option that displays the hidden keys (see [`hide()`](#hide)). + +If the first argument is a boolean, it enables/disables this option altogether. I.e. hidden keys will be permanently hidden if first argument is `false`. + +If the first argument is a string it changes the key name ("--show-hidden"). + +Second argument changes the default description ("Show hidden options") + +Example: + +```js +var yargs = require("yargs")(['--help']) + .showHidden('show-hidden', 'Show hidden options') + .argv +``` + .implies(x, y) -------------- diff --git a/lib/usage.js b/lib/usage.js index bd0906a89..c323c1bb1 100644 --- a/lib/usage.js +++ b/lib/usage.js @@ -152,16 +152,23 @@ module.exports = function usage (yargs, y18n) { const demandedCommands = yargs.getDemandedCommands() const groups = yargs.getGroups() const options = yargs.getOptions() - let keys = Object.keys( - Object.keys(descriptions) - .concat(Object.keys(demandedOptions)) - .concat(Object.keys(demandedCommands)) - .concat(Object.keys(options.default)) - .reduce((acc, key) => { - if (key !== '_') acc[key] = true - return acc - }, {}) - ) + + let keys = [] + keys = keys.concat(Object.keys(descriptions)) + keys = keys.concat(Object.keys(demandedOptions)) + keys = keys.concat(Object.keys(demandedCommands)) + keys = keys.concat(Object.keys(options.default)) + keys = keys.filter(key => { + if (options.hiddenOptions.indexOf(key) < 0) { + return true + } else if (yargs.parsed.argv[options.showHiddenOpt]) { + return true + } + }) + keys = Object.keys(keys.reduce((acc, key) => { + if (key !== '_') acc[key] = true + return acc + }, {})) const theWrap = getWrap() const ui = require('cliui')({ diff --git a/test/usage.js b/test/usage.js index e1ce066d7..611f72e42 100644 --- a/test/usage.js +++ b/test/usage.js @@ -2887,5 +2887,83 @@ describe('usage tests', () => { '' ]) }) + it('--help should display all options (including hidden ones) with --show-hidden', () => { + const r = checkUsage(() => yargs('--help --show-hidden --mama ama') + .options({ + foo: { + describe: 'FOO' + }, + bar: {}, + baz: { + describe: 'BAZ', + hidden: true + } + }) + .argv + ) + + r.logs[0].split('\n').should.deep.equal([ + 'Options:', + ' --help Show help [boolean]', + ' --version Show version number [boolean]', + ' --foo FOO', + ' --bar', + ' --baz BAZ', + '' + ]) + }) + it('--help should display --custom-show-hidden', () => { + const r = checkUsage(() => yargs('--help') + .options({ + foo: { + describe: 'FOO' + }, + bar: {}, + baz: { + describe: 'BAZ', + hidden: true + } + }) + .showHidden('custom-show-hidden') + .argv + ) + + r.logs[0].split('\n').should.deep.equal([ + 'Options:', + ' --help Show help [boolean]', + ' --version Show version number [boolean]', + ' --foo FOO', + ' --bar', + ' --custom-show-hidden Show hidden options [boolean]', + '' + ]) + }) + it('--help should display all options with --custom-show-hidden', () => { + const r = checkUsage(() => yargs('--help --custom-show-hidden') + .options({ + foo: { + describe: 'FOO' + }, + bar: {}, + baz: { + describe: 'BAZ', + hidden: true + } + }) + .showHidden('custom-show-hidden') + .argv + ) + + r.logs[0].split('\n').should.deep.equal([ + 'Options:', + ' --help Show help [boolean]', + ' --version Show version number [boolean]', + ' --foo FOO', + ' --bar', + ' --baz BAZ', + ' --custom-show-hidden Show hidden options [boolean]', + '' + ]) + }) }) }) diff --git a/test/yargs.js b/test/yargs.js index 6511250d6..70438c373 100644 --- a/test/yargs.js +++ b/test/yargs.js @@ -129,6 +129,42 @@ describe('yargs dsl tests', () => { expect(r.errors).to.deep.equal([]) }) + describe('hide', () => { + it('should add the key to hiddenOptions', () => { + const options = yargs('') + .hide('someKey') + .getOptions() + options.should.have.property('hiddenOptions') + options.hiddenOptions.should.include('someKey') + }) + }) + + describe('showHidden', () => { + it('should have a default show-hidden private option pre-configured', () => { + const options = yargs('').getOptions() + options.should.have.property('showHiddenOpt') + options.showHiddenOpt.should.eql('show-hidden') + }) + it('should not have show-hidden as an actual option described by default', () => { + const options = yargs('').getOptions() + options.key.should.not.have.property('show-hidden') + }) + it('should set show-hidden option', () => { + const options = yargs('') + .showHidden() + .getOptions() + options.key.should.have.property('show-hidden') + }) + it('should set custom-show-hidden option', () => { + const options = yargs('') + .showHidden('custom-show-hidden') + .getOptions() + options.key.should.have.property('custom-show-hidden') + options.should.have.property('showHiddenOpt') + options.showHiddenOpt.should.eql('custom-show-hidden') + }) + }) + describe('showHelpOnFail', () => { it('should display custom failure message, if string is provided as first argument', () => { const r = checkOutput(() => yargs([]) @@ -233,6 +269,7 @@ describe('yargs dsl tests', () => { config: {}, configObjects: [], envPrefix: 'YARGS', // preserved as global + hiddenOptions: [], demandedCommands: {}, demandedOptions: {}, local: [ diff --git a/yargs.js b/yargs.js index 38f1b2ea6..d9d34a47c 100644 --- a/yargs.js +++ b/yargs.js @@ -93,7 +93,8 @@ function Yargs (processArgs, cwd, parentRequire) { const arrayOptions = [ 'array', 'boolean', 'string', 'skipValidation', - 'count', 'normalize', 'number' + 'count', 'normalize', 'number', + 'hiddenOptions' ] const objectOptions = [ @@ -657,8 +658,9 @@ function Yargs (processArgs, cwd, parentRequire) { } const desc = opt.describe || opt.description || opt.desc - if (!opt.hidden) { - self.describe(key, desc) + self.describe(key, desc) + if (opt.hidden) { + self.hide(key) } if (opt.requiresArg) { @@ -824,6 +826,28 @@ function Yargs (processArgs, cwd, parentRequire) { return self } + const defaultShowHiddenOpt = 'show-hidden' + options.showHiddenOpt = defaultShowHiddenOpt + self.addShowHiddenOpt = self.showHidden = function addShowHiddenOpt (opt, msg) { + argsert('[string|boolean] [string]', [opt, msg], arguments.length) + + if (arguments.length === 1) { + if (opt === false) return self + } + + const showHiddenOpt = typeof opt === 'string' ? opt : defaultShowHiddenOpt + self.boolean(showHiddenOpt) + self.describe(showHiddenOpt, msg || usage.deferY18nLookup('Show hidden options')) + options.showHiddenOpt = showHiddenOpt + return self + } + + self.hide = function hide (key) { + argsert('', [key], arguments.length) + options.hiddenOptions.push(key) + return self + } + self.showHelpOnFail = function showHelpOnFail (enabled, message) { argsert('[boolean|string] [string]', [enabled, message], arguments.length) usage.showHelpOnFail(enabled, message)