diff --git a/lib/usage.js b/lib/usage.js index 6451c9867..9be8a995b 100644 --- a/lib/usage.js +++ b/lib/usage.js @@ -161,13 +161,7 @@ module.exports = function usage (yargs, y18n) { 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 = keys.filter(filterHiddenOptions) keys = Object.keys(keys.reduce((acc, key) => { if (key !== '_') acc[key] = true return acc @@ -251,11 +245,9 @@ module.exports = function usage (yargs, y18n) { Object.keys(groups).forEach((groupName) => { if (!groups[groupName].length) return - ui.div(__(groupName)) - // if we've grouped the key 'f', but 'f' aliases 'foobar', // normalizedKeys should contain only 'foobar'. - const normalizedKeys = groups[groupName].map((key) => { + const normalizedKeys = groups[groupName].filter(filterHiddenOptions).map((key) => { if (~aliasKeys.indexOf(key)) return key for (let i = 0, aliasKey; (aliasKey = aliasKeys[i]) !== undefined; i++) { if (~(options.alias[aliasKey] || []).indexOf(key)) return aliasKey @@ -263,6 +255,10 @@ module.exports = function usage (yargs, y18n) { return key }) + if (normalizedKeys.length < 1) return + + ui.div(__(groupName)) + // actually generate the switches string --foo, -f, --bar. const switches = normalizedKeys.reduce((acc, key) => { acc[key] = [ key ].concat(options.alias[key] || []) @@ -420,6 +416,10 @@ module.exports = function usage (yargs, y18n) { return groupedKeys } + function filterHiddenOptions (key) { + return yargs.getOptions().hiddenOptions.indexOf(key) < 0 || yargs.parsed.argv[yargs.getOptions().showHiddenOpt] + } + self.showHelp = (level) => { const logger = yargs._getLoggerInstance() if (!level) level = 'error' diff --git a/test/usage.js b/test/usage.js index 6cfad3e75..bcc216c2c 100644 --- a/test/usage.js +++ b/test/usage.js @@ -2853,6 +2853,61 @@ describe('usage tests', () => { ' --bar' ]) }) + it('--help should display all options except for hidden ones even in a group', () => { + const r = checkUsage(() => yargs('--help') + .options({ + foo: { + describe: 'FOO', + hidden: true + }, + bar: {}, + baz: { + describe: 'BAZ', + group: 'Hidden:', + hidden: true + } + }) + .parse() + ) + + r.logs[0].split('\n').should.deep.equal([ + 'Options:', + ' --help Show help [boolean]', + ' --version Show version number [boolean]', + ' --bar' + ]) + }) + it('--help should display all groups except for ones with only hidden options', () => { + const r = checkUsage(() => yargs('--help') + .options({ + foo: { + describe: 'FOO', + group: 'Hidden:', + hidden: true + }, + bar: {}, + baz: { + describe: 'BAZ', + group: 'Hidden:', + hidden: true + }, + qux: { + group: 'Shown:' + } + }) + .parse() + ) + + r.logs[0].split('\n').should.deep.equal([ + 'Shown:', + ' --qux', + '', + 'Options:', + ' --help Show help [boolean]', + ' --version Show version number [boolean]', + ' --bar' + ]) + }) it('--help should display all options (including hidden ones) with --show-hidden', () => { const r = checkUsage(() => yargs('--help --show-hidden --mama ama') .options({ @@ -2877,6 +2932,41 @@ describe('usage tests', () => { ' --baz BAZ' ]) }) + it('--help should display all groups (including ones with only hidden options) with --show-hidden', () => { + const r = checkUsage(() => yargs('--help --show-hidden') + .options({ + foo: { + describe: 'FOO', + group: 'Hidden:', + hidden: true + }, + bar: {}, + baz: { + describe: 'BAZ', + group: 'Hidden:', + hidden: true + }, + qux: { + group: 'Shown:' + } + }) + .argv + ) + + r.logs[0].split('\n').should.deep.equal([ + 'Hidden:', + ' --foo FOO', + ' --baz BAZ', + '', + 'Shown:', + ' --qux', + '', + 'Options:', + ' --help Show help [boolean]', + ' --version Show version number [boolean]', + ' --bar' + ]) + }) it('--help should display --custom-show-hidden', () => { const r = checkUsage(() => yargs('--help') .options({