Repository: okonet/lint-staged (js)

Issue:
Duplicated errors
@okonet thank you for the package.

I got duplicates in output while trying to use link-staged with husky, here's my config:

```
 "scripts": {
    "precommit": "lint-staged"
  },
  "lint-staged": {
    "gitDir": "../../",
    "linters": {
      "app/front-end/src/**/*.{js,jsx}": "eslint --quiet"
    }
  },
```

Output:

```

> husky - npm run -s precommit

[?25l[13:18:41] Running tasks for app/front-end/src/**/*.{js,jsx} [started]
[13:18:41] eslint --quiet [started]
[13:18:42] eslint --quiet [failed]
[13:18:42] → 🚫 eslint --quiet found some errors. Please fix them and try committing again.


/path/app/front-end/src/redux/actions/facebook.js
  32:24  error  'createAcffgtion' is not defined  no-undef

✖ 1 problem (1 error, 0 warnings)


[13:18:42] Running tasks for app/front-end/src/**/*.{js,jsx} [failed]
[13:18:42] → 🚫 eslint --quiet found some errors. Please fix them and try committing again.


/path/app/front-end/src/redux/actions/facebook.js
  32:24  error  'createAcffgtion' is not defined  no-undef

✖ 1 problem (1 error, 0 warnings)


[?25h🚫 eslint --quiet found some errors. Please fix them and try committing again.


/path/app/front-end/src/redux/actions/facebook.js
  32:24  error  'createAcffgtion' is not defined  no-undef

✖ 1 problem (1 error, 0 warnings)


[?25h
> husky - pre-commit hook failed (add --no-verify to bypass)
> husky - to debug, use 'npm run precommit'
```

Looks like lint-staged and husky both output the same error.
Here I got 2 errors from lint-staged and one from husky.

Can we add some --silent option for lint-staged? So it would not output the errors, but throw them forward to husky (I also use husky for another lintings).


Pull request description:
fix: Hide err msg in private field to avoid duplicate logs
This hides the error message in a private field to get around the duplicate logs issue. Most of the credit goes to @umarmw for the idea, so thank you!

Closes #142, #308, #406, #415.

Patch:
diff --git a/src/printErrors.js b/src/printErrors.js
index 6c8f24c..379e60a 100644
--- a/src/printErrors.js
+++ b/src/printErrors.js
@@ -1,11 +1,14 @@
 'use strict'
 
+// Work-around for duplicated error logs, see #142
+const errMsg = err => (err.privateMsg != null ? err.privateMsg : err.message)
+
 module.exports = function printErrors(errorInstance) {
   if (Array.isArray(errorInstance.errors)) {
     errorInstance.errors.forEach(lintError => {
-      console.error(lintError.message)
+      console.error(errMsg(lintError))
     })
   } else {
-    console.error(errorInstance.message)
+    console.error(errMsg(errorInstance))
   }
 }
diff --git a/src/runScript.js b/src/runScript.js
index c3aff87..59de46d 100644
--- a/src/runScript.js
+++ b/src/runScript.js
@@ -60,12 +60,19 @@ module.exports = function runScript(commands, pathsToLint, config) {
           const errStdout = errors.map(err => err.stdout).join('')
           const errStderr = errors.map(err => err.stderr).join('')
 
-          // prettier-ignore
-          throw new Error(dedent`
-              ${logSymbols.error} ${linter} found some errors. Please fix them and try committing again.
-              ${errStdout}
-              ${errStderr}
-            `)
+          // If we set the message on the error instance, it gets logged
+          // multiple times(see #142). So we set the actual error message in a
+          // private field and extract it later, log only once.
+          const err = new Error()
+          err.privateMsg = dedent`
+            ${
+              logSymbols.error
+            } "${linter}" found some errors. Please fix them and try committing again.
+            ${errStdout}
+            ${errStderr}
+          `
+
+          throw err
         })
     }
   }))


Test patch:
diff --git a/test/runScript.spec.js b/test/runScript.spec.js
index e0294d4..8e9f83f 100644
--- a/test/runScript.spec.js
+++ b/test/runScript.spec.js
@@ -133,9 +133,10 @@ describe('runScript', () => {
     try {
       await linter.task()
     } catch (err) {
-      // prettier-ignore
-      expect(err.message).toMatch(dedent`
-        ${logSymbols.error} mock-fail-linter found some errors. Please fix them and try committing again.
+      expect(err.privateMsg).toMatch(dedent`
+        ${
+          logSymbols.error
+        } "mock-fail-linter" found some errors. Please fix them and try committing again.
         Mock error
       `)
     }