Repository: yargs/yargs (js)

Issue:
recommended command used in conjunction with --help prints twice
```slackboard user <subcommand|help>

Commands:
  update-email <name> <email>           change email to new address for a user
  update-resource <name> <key> <value>  change resource attribute for user
  get <name>                            get user

Options:
  --help  Show help                                                                        [boolean]

Did you mean get?
/usr/bin/nodejs bin/slackboard user <subcommand|help>

Commands:
  update-email <name> <email>           change email to new address for a user
  update-resource <name> <key> <value>  change resource attribute for user
  get <name>                            get user

Options:
  --help  Show help                                                                        [boolean]```

Pull request description:
fix: we shouldn't output help if we've printed a prior help-like message
we were accidentally printing the help text twice, if recommendations were made and `exit = false`.

```bash
Commands:
  goat

Options:
  --help  Show help                                                                        [boolean]

Did you mean goat?
Commands:
  goat

Options:
  --help  Show help                                                                        [boolean]
```

Let's not do this, it looks weird!

fixes #822 

Patch:
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..3fd345c
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,14 @@
+root = true
+
+[*]
+
+indent_style = space
+indent_size = 2
+
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/yargs.js b/yargs.js
index ac0ba2e..92eb38f 100644
--- a/yargs.js
+++ b/yargs.js
@@ -1036,21 +1036,24 @@ function Yargs (processArgs, cwd, parentRequire) {
       }
 
       // Handle 'help' and 'version' options
-      Object.keys(argv).forEach(function (key) {
-        if (key === helpOpt && argv[key]) {
-          if (exitProcess) setBlocking(true)
-
-          skipValidation = true
-          self.showHelp('log')
-          self.exit(0)
-        } else if (key === versionOpt && argv[key]) {
-          if (exitProcess) setBlocking(true)
-
-          skipValidation = true
-          usage.showVersion()
-          self.exit(0)
-        }
-      })
+      // if we haven't already output help!
+      if (!hasOutput) {
+        Object.keys(argv).forEach(function (key) {
+          if (key === helpOpt && argv[key]) {
+            if (exitProcess) setBlocking(true)
+
+            skipValidation = true
+            self.showHelp('log')
+            self.exit(0)
+          } else if (key === versionOpt && argv[key]) {
+            if (exitProcess) setBlocking(true)
+
+            skipValidation = true
+            usage.showVersion()
+            self.exit(0)
+          }
+        })
+      }
 
       // Check if any of the options to skip validation were provided
       if (!skipValidation && options.skipValidation.length > 0) {


Test patch:
diff --git a/test/yargs.js b/test/yargs.js
index 078bee9..ff30871 100644
--- a/test/yargs.js
+++ b/test/yargs.js
@@ -339,6 +339,21 @@ describe('yargs dsl tests', function () {
       r.errors[1].should.match(/Did you mean goat/)
     })
 
+    // see: https://github.com/yargs/yargs/issues/822
+    it('does not print help message if recommendation has been made', function (done) {
+      const parser = yargs()
+        .command('goat')
+        .help()
+        .recommendCommands()
+
+      parser.parse('boat help', {}, function (err, _argv, output) {
+        // it should not have printed the help text twice!
+        err.message.should.equal('Did you mean goat?')
+        output.split('Commands:').length.should.equal(2)
+        return done()
+      })
+    })
+
     it("skips executing top-level command if builder's help is executed", function () {
       var r = checkOutput(function () {
         yargs(['blerg', '-h'])