Repository: yargs/yargs-parser
Pull request #84 (2017-04-15 13:52:22)

Add -- option which controls how arguments after -- flag are returned.
Implements yargs/yargs/issues/682

bcoe: @ruimarques thank you, this is great! I'm hoping to put a few hours into OSS this afternoon, and will work on landing this.

Patch:
diff --git a/README.md b/README.md
index 15ce214..ce25ce5 100644
--- a/README.md
+++ b/README.md
@@ -72,12 +72,14 @@ Parses command line arguments returning a simple mapping of keys and values.
   * `opts.string`: keys should be treated as strings (even if they resemble a number `-x 33`).
   * `opts.configuration`: provide configuration options to the yargs-parser (see: [configuration](#configuration)).
   * `opts.number`: keys should be treated as numbers.
+  * `opts['--']`: arguments after the end-of-options flag `--` will be set to the `argv.['--']` array instead of being set to the `argv._` array.
 
 **returns:**
 
 * `obj`: an object representing the parsed value of `args`
   * `key/value`: key value pairs for each argument and their aliases.
   * `_`: an array representing the positional arguments.
+  * [optional] `--`:  an array with arguments after the end-of-options flag `--`.
 
 ### require('yargs-parser').detailed(args, opts={})
 
@@ -100,6 +102,24 @@ yargs engine.
 * `configuration`: the configuration loaded from the `yargs` stanza in package.json.
 
 <a name="configuration"></a>
+
+### Options
+
+#### `--`
+* default: `false`.
+
+_If disabled:_
+```sh
+node example.js a -b -- x y
+{ _: [ 'a', 'x', 'y' ], b: true }
+```
+
+_If enabled:_
+
+```sh
+node example.js a -b -- x y
+{ _: [ 'a' ], '--': [ 'x', 'y' ], b: true }
+```
 ### Configuration
 
 The yargs-parser applies several automated transformations on the keys provided
diff --git a/index.js b/index.js
index b71faf5..25554c1 100644
--- a/index.js
+++ b/index.js
@@ -22,6 +22,8 @@ function parse (args, opts) {
   var defaults = opts.default || {}
   var configObjects = opts.configObjects || []
   var envPrefix = opts.envPrefix
+  var notFlagsOption = opts['--']
+  var notFlagsArgv = notFlagsOption ? '--' : '_'
   var newAliases = {}
   // allow a i18n handler to be passed in, default to a fake one (util.format).
   var __ = opts.__ || function (str) {
@@ -98,6 +100,10 @@ function parse (args, opts) {
 
   var argv = { _: [] }
 
+  if (notFlagsOption) {
+    argv[notFlagsArgv] = []
+  }
+
   Object.keys(flags.bools).forEach(function (key) {
     setArg(key, !(key in defaults) ? false : defaults[key])
     setDefaulted(key)
@@ -290,7 +296,7 @@ function parse (args, opts) {
   })
 
   notFlags.forEach(function (key) {
-    argv._.push(key)
+    argv[notFlagsArgv].push(key)
   })
 
   // how many arguments should we consume, based


Test patch:
diff --git a/test/yargs-parser.js b/test/yargs-parser.js
index 5b59c61..41870d0 100644
--- a/test/yargs-parser.js
+++ b/test/yargs-parser.js
@@ -1260,6 +1260,46 @@ describe('yargs-parser', function () {
     })
   })
 
+  describe('option --', function () {
+    describe('when it is not defined', function () {
+      it('should not initialize the \'--\' array', function () {
+        var result = parser([
+          'bare',
+          '--', '-h', 'eek', '--'
+        ])
+        result.should.have.property('_').and.deep.equal(['bare', '-h', 'eek', '--'])
+        result.should.not.have.property('--')
+      })
+    })
+
+    describe('when it is defined', function () {
+      it('should set bare flags to \'_\' array and non-flags to \'--\' array', function () {
+        var result = parser([
+          '--name=meowmers', 'bare', '-cats', 'woo', 'moxy',
+          '-h', 'awesome', '--multi=quux',
+          '--key', 'value',
+          '-b', '--bool', '--no-meep', '--multi=baz',
+          '--', '--not-a-flag', '-', '-h', '-multi', '--', 'eek'
+        ], {
+          '--': true
+        })
+        result.should.have.property('c', true)
+        result.should.have.property('a', true)
+        result.should.have.property('t', true)
+        result.should.have.property('s', 'woo')
+        result.should.have.property('h', 'awesome')
+        result.should.have.property('b', true)
+        result.should.have.property('bool', true)
+        result.should.have.property('key', 'value')
+        result.should.have.property('multi').and.deep.equal(['quux', 'baz'])
+        result.should.have.property('meep', false)
+        result.should.have.property('name', 'meowmers')
+        result.should.have.property('_').and.deep.equal(['bare', 'moxy'])
+        result.should.have.property('--').and.deep.equal(['--not-a-flag', '-', '-h', '-multi', '--', 'eek'])
+      })
+    })
+  })
+
   describe('count', function () {
     it('should count the number of times a boolean is present', function () {
       var parsed