Repository: yargs/yargs
Pull request #1082 (2018-03-03 08:53:50)

restructured the contents of readme
Got the logo and title to the top with center alignment and restructured the contents a bit. Let me know if you guys have any suggestions. Thanks!


Patch:
diff --git a/README.md b/README.md
index d16b82d..a09b322 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,11 @@
-# Yargs
+<p align="center">
+  <img width="250" src="/yargs-logo.png">
+</p>
+<h1 align="center"> Yargs </h1>
+<p align="center">
+  <b >Yargs be a node.js library fer hearties tryin' ter parse optstrings</b>
+</p>
+<br>
 
 [![Build Status][travis-image]][travis-url]
 [![Coverage Status][coveralls-image]][coveralls-url]
@@ -8,13 +15,10 @@
 [![Conventional Commits][conventional-commits-image]][conventional-commits-url]
 [![Slack][slack-image]][slack-url]
 
-_Having problems? want to contribute? join our [community slack](http://devtoolscommunity.herokuapp.com)_.
+## Description :
+Yargs helps you build interactive command line tools, by parsing arguments and generating an elegant user interface. 
 
-> Yargs be a node.js library fer hearties tryin' ter parse optstrings.
-
-<img width="250" src="/yargs-logo.png">
-
-Yargs helps you build interactive command line tools, by parsing arguments and generating an elegant user interface. It gives you:
+It gives you:
 
 * commands and (grouped) options (`my-program.js serve --port=5000`).
 * a dynamically generated help menu based on your arguments.
@@ -30,7 +34,9 @@ Yargs helps you build interactive command line tools, by parsing arguments and g
 npm i yargs --save
 ```
 
-## Simple Example
+## Usage :
+
+### Simple Example
 
 ````javascript
 #!/usr/bin/env node
@@ -51,9 +57,9 @@ $ ./plunder.js --ships 12 --distance 98.7
 Retreat from the xupptumblers!
 ```
 
-## Complex Example
+### Complex Example
 
-```js
+```javascript
 #!/usr/bin/env node
 require('yargs') // eslint-disable-line
   .command('serve [port]', 'start the server', (yargs) => {
@@ -75,7 +81,13 @@ require('yargs') // eslint-disable-line
 
 Run the example above with `--help` to see the help for the application.
 
-## Table of Contents
+## Community :
+
+Having problems? want to contribute? join our [community slack](http://devtoolscommunity.herokuapp.com).
+
+## Documentation :
+
+### Table of Contents
 
 * [Yargs' API](/docs/api.md)
 * [Examples](/docs/examples.md)
diff --git a/docs/api.md b/docs/api.md
index 193056b..342305e 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.
 
+<a name="hide"></a>.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
 ```
 
+<a name="showHidden"></a>.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
+```
+
 <a name="implies"></a>.implies(x, y)
 --------------
 
diff --git a/example/cmds/init.js b/example/cmds/init.js
new file mode 100644
index 0000000..ecfd314
--- /dev/null
+++ b/example/cmds/init.js
@@ -0,0 +1,10 @@
+exports.command = 'init [dir]'
+exports.desc = 'Create an empty repo'
+exports.builder = {
+  dir: {
+    default: '.'
+  }
+}
+exports.handler = function (argv) {
+  console.log('init called for dir', argv.dir)
+}
diff --git a/example/cmds/remote.js b/example/cmds/remote.js
new file mode 100644
index 0000000..e0ea5dc
--- /dev/null
+++ b/example/cmds/remote.js
@@ -0,0 +1,6 @@
+exports.command = 'remote <command>'
+exports.description = 'Manage set of tracked repos'
+exports.builder = function (yargs) {
+  return yargs.commandDir('remote_cmds')
+}
+exports.handler = function (argv) {}
diff --git a/example/cmds/remote_cmds/add.js b/example/cmds/remote_cmds/add.js
new file mode 100644
index 0000000..4f3b0e3
--- /dev/null
+++ b/example/cmds/remote_cmds/add.js
@@ -0,0 +1,6 @@
+exports.command = 'add <name> <url>'
+exports.desc = 'Add remote named <name> for repo at url <url>'
+exports.builder = {}
+exports.handler = function (argv) {
+  console.log('adding remote %s at url %s', argv.name, argv.url)
+}
diff --git a/example/cmds/remote_cmds/prune.js b/example/cmds/remote_cmds/prune.js
new file mode 100644
index 0000000..b791da8
--- /dev/null
+++ b/example/cmds/remote_cmds/prune.js
@@ -0,0 +1,6 @@
+exports.command = 'prune <name> [names..]'
+exports.desc = 'Delete tracked branches gone stale for remotes'
+exports.builder = {}
+exports.handler = function (argv) {
+  console.log('pruning remotes %s', [].concat(argv.name).concat(argv.names).join(', '))
+}
diff --git a/example/command_hierarchy.js b/example/command_hierarchy.js
new file mode 100644
index 0000000..850d4ba
--- /dev/null
+++ b/example/command_hierarchy.js
@@ -0,0 +1,6 @@
+#!/usr/bin/env node
+require('yargs')
+  .commandDir('cmds')
+  .demandCommand()
+  .help()
+  .argv
diff --git a/lib/apply-extends.js b/lib/apply-extends.js
index 530b022..1436b65 100644
--- a/lib/apply-extends.js
+++ b/lib/apply-extends.js
@@ -21,7 +21,7 @@ function applyExtends (config, cwd) {
 
   if (config.hasOwnProperty('extends')) {
     if (typeof config.extends !== 'string') return defaultConfig
-    const isPath = /\.json$/.test(config.extends)
+    const isPath = /\.json|\..*rc$/.test(config.extends)
     let pathToDefault = null
     if (!isPath) {
       try {
diff --git a/lib/usage.js b/lib/usage.js
index bd0906a..c323c1b 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/yargs.js b/yargs.js
index 38f1b2e..d9d34a4 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('<string|object>', [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)


Test patch:
diff --git a/test/fixtures/extends/.myotherrc b/test/fixtures/extends/.myotherrc
new file mode 100644
index 0000000..8c686ca
--- /dev/null
+++ b/test/fixtures/extends/.myotherrc
@@ -0,0 +1,4 @@
+{
+    "extends": "./config_1.json",
+    "c": 201
+}
\ No newline at end of file
diff --git a/test/fixtures/extends/.myrc b/test/fixtures/extends/.myrc
new file mode 100644
index 0000000..0d45cf9
--- /dev/null
+++ b/test/fixtures/extends/.myrc
@@ -0,0 +1,4 @@
+{
+    "extends": "./.myotherrc",
+    "a": 5
+}
\ No newline at end of file
diff --git a/test/usage.js b/test/usage.js
index e1ce066..611f72e 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 94f4018..70438c3 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: [
@@ -1284,6 +1321,20 @@ describe('yargs dsl tests', () => {
         argv.a.should.equal(2)
         argv.extends.should.equal('batman')
       })
+
+      it('allows files with .*rc extension to be extended', () => {
+        const argv = yargs()
+          .config({
+            extends: './test/fixtures/extends/.myrc',
+            a: 3
+          })
+          .argv
+
+        argv.a.should.equal(3)
+        argv.b.should.equal(22)
+        argv.c.should.equal(201)
+        argv.z.should.equal(15)
+      })
     })
   })