Repository: oclif/core (ts)

Issue:
oclif rejects empty string given for required argument
Do you want to request a *feature* or report a *bug*?
-----------------------------------------------------

Report a bug

What is the current behavior?
-----------------------------
oclif rejects an empty string argument when a string argument is requried

Example code:

```
import {Command, flags} from '@oclif/command'

class Foo extends Command {
  static description = 'describe the command here'

  static args = [{name: 'file', required: true}]

  async run() {
    const {args, flags} = this.parse(Foo)
  }
}

export = Foo
```

Example output:

```
$ ./bin/run
 ›   Error: Missing 1 required arg:
 ›   file
 ›   See more help with --help
$ ./bin/run ''
 ›   Error: Missing 1 required arg:
 ›   file
 ›   See more help with --help
$ ./bin/run 'foo'
$
```

The first error is expected (we omitted the argument). The second is not (we supplied an empty string as argument). In the 3rd case, the command succeeds as expected.

What is the expected behavior?
------------------------------
An empty string argument should be accepted.

I'm using oclif/command 1.8.0 on Ubuntu 20.04.


Pull request:
fix: allow arg to be empty string
Allow args to be an empty string, e.g. `my-cli hello ''`

Fixes #982 
@W-15161625@

Patch:
diff --git a/src/parser/parse.ts b/src/parser/parse.ts
index 2cf51b5..eefd9ea 100644
--- a/src/parser/parse.ts
+++ b/src/parser/parse.ts
@@ -305,7 +305,7 @@ export class Parser<
     }
 
     for (const token of tokens) {
-      if (args[token.arg]) continue
+      if (args[token.arg] !== undefined) continue
       argv.push(token.input)
     }
 
diff --git a/src/parser/validate.ts b/src/parser/validate.ts
index d2caee7..9e2b32c 100644
--- a/src/parser/validate.ts
+++ b/src/parser/validate.ts
@@ -44,7 +44,8 @@ export async function validate(parse: {input: ParserInput; output: ParserOutput}
         })
       }
 
-      if (arg.required && !parse.output.args[name] && parse.output.args[name] !== 0) {
+      // Only add if it's required and undefined. Allow falsy values like empty strings and 0.
+      if (arg.required && parse.output.args[name] === undefined) {
         missingRequiredArgs.push(arg)
       }
     }


Test patch:
diff --git a/test/parser/validate.test.ts b/test/parser/validate.test.ts
index ac9ee6d..b85fa1b 100644
--- a/test/parser/validate.test.ts
+++ b/test/parser/validate.test.ts
@@ -121,6 +121,31 @@ describe('validate', () => {
     await validate({input, output})
   })
 
+  it('allows empty string as arg', async () => {
+    const input = {
+      argv: [],
+      flags: {},
+      args: {
+        emptyString: {required: true},
+      },
+      strict: true,
+      context: {},
+      '--': true,
+    }
+
+    const output = {
+      args: {emptyString: ''},
+      argv: [''],
+      raw: [],
+      metadata: {
+        flags: {},
+      },
+    }
+
+    // @ts-expect-error
+    await validate({input, output})
+  })
+
   it('throws when required flag is undefined', async () => {
     const input = {
       argv: [],