Repository: yargs/yargs-parser
Pull request #26 (2016-04-10 08:36:37)

feat(environment): Support nested options in environment variables
It uses the '__' syntax to indicate nested properties, based on prior art from
https://github.com/indexzero/nconf#env and https://github.com/dominictarr/rc.

Closes yargs/yargs#332

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

Coverage remained the same at 100.0% when pulling **d939b8ee01777111c2dacfdf87c76f56da751157 on elas7:nested-env** into **f16acbd7af013b4485b9320aa5a2aa991c7a4517 on yargs:master**.


Patch:
diff --git a/index.js b/index.js
index 2838f68..0abbb3b 100644
--- a/index.js
+++ b/index.js
@@ -455,9 +455,16 @@ function parse (args, opts) {
     var prefix = typeof envPrefix === 'string' ? envPrefix : ''
     Object.keys(process.env).forEach(function (envVar) {
       if (prefix === '' || envVar.lastIndexOf(prefix, 0) === 0) {
-        var key = camelCase(envVar.substring(prefix.length))
-        if (((configOnly && flags.configs[key]) || !configOnly) && (!(key in argv) || flags.defaulted[key])) {
-          setArg(key, process.env[envVar])
+        // get array of nested keys and convert them to camel case
+        var keys = envVar.split('__').map(function (key, i) {
+          if (i === 0) {
+            key = key.substring(prefix.length)
+          }
+          return camelCase(key)
+        })
+
+        if (((configOnly && flags.configs[keys.join('.')]) || !configOnly) && (!hasKey(argv, keys) || flags.defaulted[keys.join('.')])) {
+          setArg(keys.join('.'), process.env[envVar])
         }
       }
     })
diff --git a/package.json b/package.json
index b314467..4272d28 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,7 @@
     "mocha": "^2.4.5",
     "nyc": "^6.1.1",
     "standard": "^6.0.8",
-    "standard-version": "^1.1.0"
+    "standard-version": "^2.1.2"
   },
   "dependencies": {
     "camelcase": "^2.1.1",


Test patch:
diff --git a/test/yargs-parser.js b/test/yargs-parser.js
index eb14c59..17c2c8b 100644
--- a/test/yargs-parser.js
+++ b/test/yargs-parser.js
@@ -1641,6 +1641,39 @@ describe('yargs-parser', function () {
       result.should.have.property('truthy')
       result.z.should.equal(55)
     })
+
+    it('should apply all nested env vars', function () {
+      process.env.TEST_A = 'a'
+      process.env.TEST_NESTED_OPTION__FOO = 'baz'
+      process.env.TEST_NESTED_OPTION__BAR = 'bar'
+      var result = parser(['--nestedOption.foo', 'bar'], {
+        envPrefix: 'TEST'
+      })
+
+      result.should.have.property('a', 'a')
+      result.should.have.property('nestedOption').and.deep.equal({
+        foo: 'bar',
+        bar: 'bar'
+      })
+    })
+
+    it('should apply nested env var if argv value is using default value', function () {
+      process.env.TEST_A = 'a'
+      process.env.TEST_NESTED_OPTION__FOO = 'baz'
+      process.env.TEST_NESTED_OPTION__BAR = 'bar'
+      var result = parser([], {
+        envPrefix: 'TEST',
+        default: {
+          'nestedOption.foo': 'banana'
+        }
+      })
+
+      result.should.have.property('a', 'a')
+      result.should.have.property('nestedOption').and.deep.equal({
+        foo: 'baz',
+        bar: 'bar'
+      })
+    })
   })
 
   describe('configuration', function () {