Repository: oclif/core (ts)

Issue:
Boolean flags don't read environment variables
**Describe the bug**
Boolean flags do not read environment variables.

**To Reproduce**
Steps to reproduce the behavior:
Create a command with a boolean flag and try use an environment variable to enable the flag.

**Expected behavior**
It is possible to pass the `env` option to a boolean flag, so boolean flags should take env variables into consideration and check them for truthy values.


Pull request description:
fix: support environment variables for boolean flags (#488)

Patch:
diff --git a/src/parser/parse.ts b/src/parser/parse.ts
index d0eb4bd..a7d965e 100644
--- a/src/parser/parse.ts
+++ b/src/parser/parse.ts
@@ -198,13 +198,18 @@ export class Parser<T extends ParserInput, TFlags extends OutputFlags<T['flags']
     for (const k of Object.keys(this.input.flags)) {
       const flag = this.input.flags[k]
       if (flags[k]) continue
-      if (flag.type === 'option' && flag.env) {
+      if (flag.env) {
         const input = process.env[flag.env]
-        if (input) {
-          this._validateOptions(flag, input)
+        if (flag.type === 'option') {
+          if (input) {
+            this._validateOptions(flag, input)
 
-          // eslint-disable-next-line no-await-in-loop
-          flags[k] = await flag.parse(input, this.context, flag)
+            // eslint-disable-next-line no-await-in-loop
+            flags[k] = await flag.parse(input, this.context, flag)
+          }
+        } else if (flag.type === 'boolean') {
+          // eslint-disable-next-line no-negated-condition
+          flags[k] = input !== undefined ? ['true', 'TRUE', '1', 'yes', 'YES', 'y', 'Y'].includes(input) : false
         }
       }
 


Test patch:
diff --git a/test/parser/parse.test.ts b/test/parser/parse.test.ts
index 49afcc9..45d1403 100644
--- a/test/parser/parse.test.ts
+++ b/test/parser/parse.test.ts
@@ -860,13 +860,45 @@ See more help with --help`)
   })
 
   describe('env', () => {
-    it('accepts as environment variable', async () => {
-      process.env.TEST_FOO = '101'
-      const out = await parse([], {
-        flags: {foo: flags.string({env: 'TEST_FOO'})},
+    describe('string', () => {
+      it('accepts as environment variable', async () => {
+        process.env.TEST_FOO = '101'
+        const out = await parse([], {
+          flags: {foo: flags.string({env: 'TEST_FOO'})},
+        })
+        expect(out.flags.foo).to.equal('101')
+        delete process.env.TEST_FOO
       })
-      expect(out.flags.foo).to.equal('101')
-      delete process.env.TEST_FOO
+    })
+
+    describe('boolean', () => {
+      const truthy = ['true', 'TRUE', '1', 'yes', 'YES', 'y', 'Y']
+      for (const value of truthy) {
+        it(`accepts '${value}' as a truthy environment variable`, async () => {
+          process.env.TEST_FOO = value
+          const out = await parse([], {
+            flags: {
+              foo: flags.boolean({env: 'TEST_FOO'}),
+            },
+          })
+          expect(out.flags.foo).to.be.true
+          delete process.env.TEST_FOO
+        })
+      }
+
+      const falsy = ['false', 'FALSE', '0', 'no', 'NO', 'n', 'N']
+      for (const value of falsy) {
+        it(`accepts '${value}' as a falsy environment variable`, async () => {
+          process.env.TEST_FOO = value
+          const out = await parse([], {
+            flags: {
+              foo: flags.boolean({env: 'TEST_FOO'}),
+            },
+          })
+          expect(out.flags.foo).to.be.false
+          delete process.env.TEST_FOO
+        })
+      }
     })
   })