Repository: oclif/core
Pull request #231 (2021-08-18 14:54:19)

fix: command name parsing when flag=value present
[skip-validate-pr]


Patch:
diff --git a/src/help/util.ts b/src/help/util.ts
index 0c7c2fc..be04d0f 100644
--- a/src/help/util.ts
+++ b/src/help/util.ts
@@ -44,18 +44,19 @@ function collateSpacedCmdIDFromArgs(argv: string[], config: IConfig): string[] {
     const final: string[] = []
     const idPresent = (id: string) => ids.includes(id)
     const isFlag = (s: string) => s.startsWith('-')
+    const isArgWithValue = (s: string) => s.includes('=')
     const finalizeId = (s?: string) => s ? [...final, s].join(':') : final.join(':')
 
     const hasSubCommandsWithArgs = () => {
       const subCommands = config.commands.filter(c => (c.id).startsWith(finalizeId()))
-      return Boolean(subCommands.find(cmd => cmd.strict === false || cmd.args.length > 0))
+      return Boolean(subCommands.find(cmd => cmd.strict === false || cmd.args?.length > 0))
     }
 
     for (const arg of argv) {
       if (idPresent(finalizeId(arg))) final.push(arg)
       // If the parent topic has a command that expects positional arguments, then we cannot
       // assume that any subsequent string could be part of the command name
-      else if (isFlag(arg) || hasSubCommandsWithArgs()) break
+      else if (isArgWithValue(arg) || isFlag(arg) || hasSubCommandsWithArgs()) break
       else final.push(arg)
     }
 


Test patch:
diff --git a/test/help/util.test.ts b/test/help/util.test.ts
index 7c1e791..914474a 100644
--- a/test/help/util.test.ts
+++ b/test/help/util.test.ts
@@ -90,6 +90,18 @@ describe('util', () => {
       expect(actual).to.deep.equal(['foo:bar', 'baz'])
     })
 
+    test
+    .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar'])
+    .it('should return standardized id when topic separator is a space and has variable arguments and flags', () => {
+      config.topicSeparator = ' '
+      config.commands.push({
+        id: 'foo:bar',
+        strict: false,
+      } as any)
+      const actual = standardizeIDFromArgv(['foo', 'bar', 'baz', '--hello'], config)
+      expect(actual).to.deep.equal(['foo:bar', 'baz', '--hello'])
+    })
+
     test
     .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar'])
     .it('should return full id when topic separator is a space and does not have arguments', () => {
@@ -102,5 +114,45 @@ describe('util', () => {
       const actual = standardizeIDFromArgv(['foo', 'bar', 'baz'], config)
       expect(actual).to.deep.equal(['foo:bar:baz'])
     })
+
+    test
+    .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar'])
+    .it('should return standardized id when topic separator is a space and has arg with value', () => {
+      config.topicSeparator = ' '
+      config.commands.push({id: 'foo:bar'} as any)
+      const actual = standardizeIDFromArgv(['foo', 'bar', 'hello=world'], config)
+      expect(actual).to.deep.equal(['foo:bar', 'hello=world'])
+    })
+
+    test
+    .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar'])
+    .it('should return standardized id when topic separator is a space and has variable args with value', () => {
+      config.topicSeparator = ' '
+      config.commands.push({id: 'foo:bar', strict: false} as any)
+      const actual = standardizeIDFromArgv(['foo', 'bar', 'hello=world', 'my-arg=value'], config)
+      expect(actual).to.deep.equal(['foo:bar', 'hello=world', 'my-arg=value'])
+    })
+
+    test
+    .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar'])
+    .it('should return standardized id when topic separator is a space and has flags', () => {
+      config.topicSeparator = ' '
+      config.commands.push({id: 'foo:bar'} as any)
+      const actual = standardizeIDFromArgv(['foo', 'bar', '--baz'], config)
+      expect(actual).to.deep.equal(['foo:bar', '--baz'])
+    })
+
+    test
+    .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar'])
+    .it('should return standardized id when topic separator is a space and has flags, arg, and arg with value', () => {
+      config.topicSeparator = ' '
+      config.commands.push({
+        id: 'foo:bar',
+        args: [{name: 'my-arg'}],
+        strict: true,
+      } as any)
+      const actual = standardizeIDFromArgv(['foo', 'bar', 'my-arg', 'hello=world', '--baz'], config)
+      expect(actual).to.deep.equal(['foo:bar', 'my-arg', 'hello=world', '--baz'])
+    })
   })
 })