Repository: yargs/yargs-parser
Pull request #18 (2016-04-03 03:10:50)

Handle calling short option with an empty string as the next value.
Calling with a short option followed by a falsy value (like the empty string `""`) results in the value not applied to the flag.

For example, calling `-f ""` results in `{'_':[""], 'f':true}` instead of `{'_':[], 'f':""}`

I fixed this by updating the check to look like the one in the `--foo ""` case, where it works fine.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/5642487/badge)](https://coveralls.io/builds/5642487)

Coverage remained the same at 100.0% when pulling **aebd4aee68be6cb8e08ea674b63db0974f9f7d7a on elas7:fix-empty** into **48b1e6a338f80417b3fd0fc3e39ae181332fdcb5 on yargs:master**.


Patch:
diff --git a/.npmignore b/.npmignore
deleted file mode 100644
index a399f75..0000000
--- a/.npmignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.nyc_output
-node_modules
-.DS_Store
-yargs-logo.png
-./test/fixtures/package.json
diff --git a/index.js b/index.js
index 834f8da..2f0c17e 100644
--- a/index.js
+++ b/index.js
@@ -240,12 +240,12 @@ function parse (args, opts) {
         } else {
           next = args[i + 1]
 
-          if (next && !/^(-|--)[^-]/.test(next) &&
+          if (next !== undefined && !/^(-|--)[^-]/.test(next) &&
             !checkAllAliases(key, flags.bools) &&
             !checkAllAliases(key, flags.counts)) {
             setArg(key, next)
             i++
-          } else if (next && /true|false/.test(next)) {
+          } else if (/true|false/.test(next)) {
             setArg(key, next)
             i++
           } else {
@@ -335,6 +335,11 @@ function parse (args, opts) {
       value = increment
     }
 
+    // Set normalized value when key is in 'normalize' and in 'arrays'
+    if (checkAllAliases(key, flags.normalize) && checkAllAliases(key, flags.arrays)) {
+      value = path.normalize(val)
+    }
+
     var splitKey = key.split('.')
     setKey(argv, splitKey, value)
 
@@ -361,20 +366,18 @@ function parse (args, opts) {
       setKey(argv, x, value)
     })
 
-    var keys = [key].concat(flags.aliases[key] || [])
-    for (var i = 0, l = keys.length; i < l; i++) {
-      if (flags.normalize[keys[i]]) {
-        keys.forEach(function (key) {
-          argv.__defineSetter__(key, function (v) {
-            val = path.normalize(v)
-          })
-
-          argv.__defineGetter__(key, function () {
-            return typeof val === 'string' ? path.normalize(val) : val
-          })
+    // Set normalize getter and setter when key is in 'normalize' but isn't an array
+    if (checkAllAliases(key, flags.normalize) && !checkAllAliases(key, flags.arrays)) {
+      var keys = [key].concat(flags.aliases[key] || [])
+      keys.forEach(function (key) {
+        argv.__defineSetter__(key, function (v) {
+          val = path.normalize(v)
         })
-        break
-      }
+
+        argv.__defineGetter__(key, function () {
+          return typeof val === 'string' ? path.normalize(val) : val
+        })
+      })
     }
   }
 
@@ -494,7 +497,7 @@ function parse (args, opts) {
       o[key] = increment(o[key])
     } else if (o[key] === undefined && checkAllAliases(key, flags.arrays)) {
       o[key] = Array.isArray(value) ? value : [value]
-    } else if (o[key] === undefined || typeof o[key] === 'boolean') {
+    } else if (o[key] === undefined || checkAllAliases(key, flags.bools)) {
       o[key] = value
     } else if (Array.isArray(o[key])) {
       o[key].push(value)
diff --git a/package.json b/package.json
index c2429e4..228265f 100644
--- a/package.json
+++ b/package.json
@@ -34,5 +34,9 @@
   "dependencies": {
     "camelcase": "^2.1.1",
     "lodash.assign": "^4.0.6"
-  }
+  },
+  "files": [
+    "lib",
+    "index.js"
+  ]
 }


Test patch:
diff --git a/test/yargs-parser.js b/test/yargs-parser.js
index ca1476c..87c54dd 100644
--- a/test/yargs-parser.js
+++ b/test/yargs-parser.js
@@ -40,6 +40,12 @@ describe('yargs-parser', function () {
     parse.should.have.property('_').with.length(0)
   })
 
+  it('should set the value of a single long option to the next supplied value, even if the value is empty', function () {
+    var parse = parser(['--pow', ''])
+    parse.should.have.property('pow', '')
+    parse.should.have.property('_').with.length(0)
+  })
+
   it('should set the value of a single long option if an = was used', function () {
     var parse = parser(['--pow=xixxle'])
     parse.should.have.property('pow', 'xixxle')
@@ -121,6 +127,12 @@ describe('yargs-parser', function () {
     argv._[0].should.be.a('number')
   })
 
+  it('should set the value of a single short option to the next supplied value, even if the value is empty', function () {
+    var parse = parser(['-p', ''])
+    parse.should.have.property('p', '')
+    parse.should.have.property('_').with.length(0)
+  })
+
   it('should not set the next value as the value of a short option if that option is explicitly defined as a boolean', function () {
     var parse = parser([ '-t', 'moo' ], {
       boolean: 't'
@@ -236,6 +248,19 @@ describe('yargs-parser', function () {
       a.s = ['', 'path', 'to', 'new', 'dir', '..', '..', ''].join(path.sep)
       a.s.should.equal(['', 'path', 'to', ''].join(path.sep))
     })
+
+    it('should normalize when key is also an array', function () {
+      var a = parser([ '-s', ['', 'tmp', '..', ''].join(path.sep), ['', 'path', 'to', 'new', 'dir', '..', '..', ''].join(path.sep) ], {
+        alias: {
+          s: ['save']
+        },
+        normalize: 's',
+        array: 's'
+      })
+      var expected = [path.sep, ['', 'path', 'to', ''].join(path.sep)]
+      a.should.have.property('s').and.deep.equal(expected)
+      a.should.have.property('save').and.deep.equal(expected)
+    })
   })
 
   describe('alias', function () {
@@ -866,7 +891,7 @@ describe('yargs-parser', function () {
     })
 
     describe('for boolean options', function () {
-      [true, false, undefined].forEach(function (def) {
+      [true, false, undefined, null].forEach(function (def) {
         describe('with explicit ' + def + ' default', function () {
           var opts = {
             default: {