Repository: yargs/yargs (js)

Issue:
.option('x', { normalize: false }) still normalizes the option 
Yargs 8.0.2 still normalizes an argument even if a values of `false` is passed to options.

```javascript
#!/usr/bin/env node
"use strict";
const yargs = require('yargs');
yargs.option('database', { normalize: false });
console.log(yargs.argv.database);
```
Notice how the slash in the URL is removed:
```
> ./normalize-test.js --database mongodb://url
mongodb:/url
```
Is this because the code is just checking for the key presence rather than the actual value?
https://github.com/yargs/yargs/blob/a40cbc95277037b614c6a36b817ad31d4327fdae/yargs.js#L594

Pull request description:
Fix #947 - config and normalise can be disabled with false

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e0631dc..0b5c810 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,31 @@
 
 All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
 
+<a name="9.1.0"></a>
+# [9.1.0](https://github.com/yargs/yargs/compare/v9.0.1...v9.1.0) (2017-09-25)
+
+
+### Bug Fixes
+
+* **command:** Run default cmd even if the only cmd ([#950](https://github.com/yargs/yargs/issues/950)) ([7b22203](https://github.com/yargs/yargs/commit/7b22203))
+
+
+### Features
+
+* multiple usage calls are now collected, not replaced ([#958](https://github.com/yargs/yargs/issues/958)) ([74a38b2](https://github.com/yargs/yargs/commit/74a38b2))
+
+
+
+<a name="9.0.1"></a>
+## [9.0.1](https://github.com/yargs/yargs/compare/v9.0.0...v9.0.1) (2017-09-17)
+
+
+### Bug Fixes
+
+* implications fails only displayed once ([#954](https://github.com/yargs/yargs/issues/954)) ([ac8088b](https://github.com/yargs/yargs/commit/ac8088b))
+
+
+
 <a name="9.0.0"></a>
 # [9.0.0](https://github.com/yargs/yargs/compare/v8.0.2...v9.0.0) (2017-09-03)
 
diff --git a/lib/usage.js b/lib/usage.js
index 47cbf75..16c4b19 100644
--- a/lib/usage.js
+++ b/lib/usage.js
@@ -64,11 +64,21 @@ module.exports = function usage (yargs, y18n) {
   }
 
   // methods for ouputting/building help (usage) message.
-  let usage
+  let usages = []
+  let usageDisabled = false
   self.usage = (msg) => {
-    usage = msg
+    if (msg === null) {
+      usageDisabled = true
+      usages = []
+      return
+    }
+    usageDisabled = false
+    usages.push(msg)
+  }
+  self.getUsage = () => {
+    if (usageDisabled) return null
+    return usages.reduce((usageMsg, msg) => `${usageMsg}${msg}\n`, '') || undefined
   }
-  self.getUsage = () => usage
 
   let examples = []
   self.example = (cmd, description) => {
@@ -151,9 +161,9 @@ module.exports = function usage (yargs, y18n) {
     })
 
     // the usage string.
-    if (usage) {
-      const u = usage.replace(/\$0/g, yargs.$0)
-      ui.div(`${u}\n`)
+    if (usages.length && !usageDisabled) {
+      const u = self.getUsage().replace(/\$0/g, yargs.$0)
+      ui.div(`${u}`)
     }
 
     // your application's commands, i.e., non-option
@@ -435,7 +445,8 @@ module.exports = function usage (yargs, y18n) {
     // do not reset fails here
     failMessage = null
     failureOutput = false
-    usage = undefined
+    usages = []
+    usageDisabled = false
     epilog = undefined
     examples = []
     commands = []
@@ -448,7 +459,8 @@ module.exports = function usage (yargs, y18n) {
     frozen = {}
     frozen.failMessage = failMessage
     frozen.failureOutput = failureOutput
-    frozen.usage = usage
+    frozen.usages = usages
+    frozen.usageDisabled = usageDisabled
     frozen.epilog = epilog
     frozen.examples = examples
     frozen.commands = commands
@@ -457,7 +469,8 @@ module.exports = function usage (yargs, y18n) {
   self.unfreeze = function unfreeze () {
     failMessage = frozen.failMessage
     failureOutput = frozen.failureOutput
-    usage = frozen.usage
+    usages = frozen.usages
+    usageDisabled = frozen.usageDisabled
     epilog = frozen.epilog
     examples = frozen.examples
     commands = frozen.commands
diff --git a/lib/validation.js b/lib/validation.js
index 0b322a3..1eee2fb 100644
--- a/lib/validation.js
+++ b/lib/validation.js
@@ -249,6 +249,7 @@ module.exports = function validation (yargs, usage, y18n) {
       ;(implied[key] || []).forEach((value) => {
         let num
         let key = origKey
+        const origValue = value
 
         // convert string '1' to number 1
         num = Number(key)
@@ -278,7 +279,7 @@ module.exports = function validation (yargs, usage, y18n) {
           value = argv[value]
         }
         if (key && !value) {
-          implyFail.push(origKey)
+          implyFail.push(` ${origKey} -> ${origValue}`)
         }
       })
     })
@@ -286,12 +287,8 @@ module.exports = function validation (yargs, usage, y18n) {
     if (implyFail.length) {
       let msg = `${__('Implications failed:')}\n`
 
-      implyFail.forEach((key) => {
-        if (implied[key]) {
-          implied[key].forEach((value) => {
-            msg += (` ${key} -> ${value}`)
-          })
-        }
+      implyFail.forEach((value) => {
+        msg += (value)
       })
 
       usage.fail(msg)
diff --git a/package.json b/package.json
index 49097a0..2e9774b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "yargs",
-  "version": "9.0.0",
+  "version": "9.1.0",
   "description": "yargs the modern, pirate-themed, successor to optimist.",
   "main": "./index.js",
   "files": [
diff --git a/yargs.js b/yargs.js
index 8ea1c42..fa3c23d 100644
--- a/yargs.js
+++ b/yargs.js
@@ -572,10 +572,6 @@ function Yargs (processArgs, cwd, parentRequire) {
         self.demandOption(key, typeof opt.demandOption === 'string' ? opt.demandOption : undefined)
       }
 
-      if ('config' in opt) {
-        self.config(key, opt.configParser)
-      }
-
       if ('conflicts' in opt) {
         self.conflicts(key, opt.conflicts)
       }
@@ -592,7 +588,11 @@ function Yargs (processArgs, cwd, parentRequire) {
         self.nargs(key, opt.nargs)
       }
 
-      if ('normalize' in opt) {
+      if (opt.config) {
+        self.config(key, opt.configParser)
+      }
+
+      if (opt.normalize) {
         self.normalize(key)
       }
 
@@ -985,6 +985,9 @@ function Yargs (processArgs, cwd, parentRequire) {
           if (recommendCommands && firstUnknownCommand && !argv[helpOpt]) {
             validation.recommendCommands(firstUnknownCommand, handlerKeys)
           }
+        } else if (command.hasDefaultCommand() && !argv[helpOpt]) {
+          setPlaceholderKeys(argv)
+          return command.runCommand(null, self, parsed)
         }
 
         // generate a completion script for adding to ~/.bashrc.


Test patch:
diff --git a/test/command.js b/test/command.js
index cd3f840..6bc28ae 100644
--- a/test/command.js
+++ b/test/command.js
@@ -1198,6 +1198,26 @@ describe('Command', () => {
         .argv
     })
 
+    it('executes default command if undefined positional arguments and only command', (done) => {
+      yargs('baz --foo bar')
+        .command('*', 'default command', noop, (argv) => {
+          argv.foo.should.equal('bar')
+          argv._.should.contain('baz')
+          return done()
+        })
+        .argv
+    })
+
+    it('executes default command if defined positional arguments and only command', (done) => {
+      yargs('baz --foo bar')
+        .command('* <target>', 'default command', noop, (argv) => {
+          argv.foo.should.equal('bar')
+          argv.target.should.equal('baz')
+          return done()
+        })
+        .argv
+    })
+
     it('does not execute default command if another command is provided', (done) => {
       yargs('run bcoe --foo bar')
         .command('*', 'default command', noop, (argv) => {})
diff --git a/test/usage.js b/test/usage.js
index 8b5c3dc..5ed522f 100644
--- a/test/usage.js
+++ b/test/usage.js
@@ -1817,6 +1817,39 @@ describe('usage tests', () => {
         ''
       ])
     })
+
+    it('allows a builder to add more than one usage with mutiple usage calls', () => {
+      const r = checkUsage(() => yargs('upload --help')
+        .command('upload', 'upload something', yargs => yargs.usage('$0 upload [something]').usage('$0 upload [something else]'), (argv) => {})
+        .wrap(null)
+        .argv
+      )
+
+      r.logs[0].split('\n').should.deep.equal([
+        './usage upload [something]',
+        './usage upload [something else]',
+        '',
+        'Options:',
+        '  --help     Show help  [boolean]',
+        '  --version  Show version number  [boolean]',
+        ''
+      ])
+    })
+
+    it('allows a builder to disable usage with null after mutiple usage calls', () => {
+      const r = checkUsage(() => yargs('upload --help')
+        .command('upload', 'upload something', yargs => yargs.usage('$0 upload [something]').usage('$0 upload [something else]').usage(null), (argv) => {})
+        .wrap(null)
+        .argv
+      )
+
+      r.logs[0].split('\n').should.deep.equal([
+        'Options:',
+        '  --help     Show help  [boolean]',
+        '  --version  Show version number  [boolean]',
+        ''
+      ])
+    })
   })
 
   describe('epilogue', () => {
diff --git a/test/validation.js b/test/validation.js
index b65c19f..ff9a607 100644
--- a/test/validation.js
+++ b/test/validation.js
@@ -38,15 +38,17 @@ describe('validation tests', () => {
         .argv
     })
 
-    it('fails if either implied argument is not set', (done) => {
+    it('fails if either implied argument is not set and displays only failed', (done) => {
       yargs(['-f', '-b'])
           .implies('f', ['b', 'c'])
           .fail((msg1) => {
             yargs(['-f', '-c'])
                 .implies('f', ['b', 'c'])
                 .fail((msg2) => {
-                  msg1.should.match(/f -> b f -> c/)
-                  msg2.should.match(/f -> b f -> c/)
+                  msg1.should.match(/f -> c/)
+                  msg1.should.not.match(/f -> b/)
+                  msg2.should.match(/f -> b/)
+                  msg2.should.not.match(/f -> c/)
                   return done()
                 })
                 .argv
diff --git a/test/yargs.js b/test/yargs.js
index ef9f860..66dd67b 100644
--- a/test/yargs.js
+++ b/test/yargs.js
@@ -1186,6 +1186,17 @@ describe('yargs dsl tests', () => {
       argv.foo.should.equal('baz')
     })
 
+    it('can be disabled with option shorthand', () => {
+      const argv = yargs('--config ./test/fixtures/config.json')
+        .option('config', {
+          config: false,
+          global: false
+        })
+        .argv
+
+      argv.config.should.equal('./test/fixtures/config.json')
+    })
+
     it('allows to pass a configuration object', () => {
       const argv = yargs
           .config({foo: 1, bar: 2})
@@ -1285,6 +1296,17 @@ describe('yargs dsl tests', () => {
       argv.path = '/foo/bar//baz/asdf/quux/..'
       argv.path.should.equal(['', 'foo', 'bar', 'baz', 'asdf'].join(path.sep))
     })
+
+    it('can be disabled with option shorthand', () => {
+      const argv = yargs('--path /batman')
+        .option('path', {
+          normalize: false
+        })
+        .argv
+
+      argv.path = 'mongodb://url'
+      argv.path.should.equal('mongodb://url')
+    })
   })
 
   describe('narg', () => {