Repository: yargs/yargs
Pull request #633 (2016-09-26 05:46:58)

chore: upgrade yargs-parser
BREAKING CHANGE: coerce is now applied as a final step after other parsing is complete

CC: @maxrimue 

maxrimue: @bcoe added the documentation, what do you think?

Patch:
diff --git a/README.md b/README.md
index 5547ca6..319be65 100644
--- a/README.md
+++ b/README.md
@@ -461,10 +461,17 @@ command line for `key`.
 The coercion function should accept one argument, representing the parsed value
 from the command line, and should return a new value or throw an error. The
 returned value will be used as the value for `key` (or one of its aliases) in
-`argv`. If the function throws, the error will be treated as a validation
+`argv`.
+
+If the function throws, the error will be treated as a validation
 failure, delegating to either a custom [`.fail()`](#fail) handler or printing
 the error message in the console.
 
+Coercion will be applied to a value after
+all other modifications, such as [`.normalize()`](#normalize).
+
+_Examples:_
+
 ```js
 var argv = require('yargs')
   .coerce('file', function (arg) {
@@ -495,6 +502,22 @@ var argv = require('yargs')
   .argv
 ```
 
+If you are using dot-notion or arrays, .e.g., `user.email` and `user.password`,
+coercion will be applied to the final object that has been parsed:
+
+```js
+// --user.name Batman --user.password 123
+// gives us: {name: 'batman', password: '[SECRET]'}
+var argv = require('yargs')
+  .option('user')
+  .coerce('user', opt => {
+    opt.name = opt.name.toLowerCase()
+    opt.password = '[SECRET]'
+    return opt
+  })
+  .argv
+```
+
 .command(cmd, desc, [builder], [handler])
 -----------------------------------------
 .command(cmd, desc, [module])
diff --git a/lib/assign.js b/lib/assign.js
new file mode 100644
index 0000000..7d5a3ce
--- /dev/null
+++ b/lib/assign.js
@@ -0,0 +1,15 @@
+// lazy Object.assign logic that only works for merging
+// two objects; eventually we should replace this with Object.assign.
+module.exports = function assign (defaults, configuration) {
+  var o = {}
+  configuration = configuration || {}
+
+  Object.keys(defaults).forEach(function (k) {
+    o[k] = defaults[k]
+  })
+  Object.keys(configuration).forEach(function (k) {
+    o[k] = configuration[k]
+  })
+
+  return o
+}
diff --git a/package.json b/package.json
index 59ecaac..b47aa55 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,6 @@
     "cliui": "^3.2.0",
     "decamelize": "^1.1.1",
     "get-caller-file": "^1.0.1",
-    "lodash.assign": "^4.2.0",
     "os-locale": "^1.4.0",
     "read-pkg-up": "^1.0.1",
     "require-directory": "^2.1.1",
@@ -25,7 +24,7 @@
     "which-module": "^1.0.0",
     "window-size": "^0.2.0",
     "y18n": "^3.2.1",
-    "yargs-parser": "^3.2.0"
+    "yargs-parser": "^4.0.2"
   },
   "devDependencies": {
     "chai": "^3.4.1",
@@ -33,12 +32,12 @@
     "coveralls": "^2.11.11",
     "cpr": "^2.0.0",
     "cross-spawn": "^4.0.0",
-    "es6-promise": "^3.0.2",
+    "es6-promise": "^4.0.2",
     "hashish": "0.0.4",
     "mocha": "^3.0.1",
     "nyc": "^8.1.0",
     "rimraf": "^2.5.0",
-    "standard": "^8.0.0",
+    "standard": "^8.2.0",
     "standard-version": "^2.2.1",
     "which": "^1.2.9"
   },
@@ -70,5 +69,10 @@
   "license": "MIT",
   "engine": {
     "node": ">=0.10"
+  },
+  "greenkeeper": {
+    "ignore": [
+      "string-width"
+    ]
   }
 }
diff --git a/yargs.js b/yargs.js
index 13fd676..abe2ec8 100644
--- a/yargs.js
+++ b/yargs.js
@@ -504,7 +504,7 @@ function Yargs (processArgs, cwd, parentRequire) {
   }
   self.getGroups = function () {
     // combine explicit and preserved groups. explicit groups should be first
-    return require('lodash.assign')({}, groups, preservedGroups)
+    return require('./lib/assign')(groups, preservedGroups)
   }
 
   // as long as options.envPrefix is not undefined,
@@ -824,7 +824,7 @@ function Yargs (processArgs, cwd, parentRequire) {
     // Check if any of the options to skip validation were provided
     if (!skipValidation && options.skipValidation.length > 0) {
       skipValidation = Object.keys(argv).some(function (key) {
-        return options.skipValidation.indexOf(key) >= 0
+        return options.skipValidation.indexOf(key) >= 0 && argv[key] === true
       })
     }
 


Test patch:
diff --git a/test/yargs.js b/test/yargs.js
index 703ce40..75d129d 100644
--- a/test/yargs.js
+++ b/test/yargs.js
@@ -1051,6 +1051,20 @@ describe('yargs dsl tests', function () {
           .argv
       argv.koala.should.equal(true)
     })
+
+    it('allows having an option that skips validation but not skipping validation if that option is not used', function () {
+      var skippedValidation = true
+      yargs(['--no-skip'])
+          .demand(5)
+          .option('skip', {
+            skipValidation: true
+          })
+          .fail(function (msg) {
+            skippedValidation = false
+          })
+          .argv
+      expect(skippedValidation).to.equal(false)
+    })
   })
 
   describe('.help()', function () {