Repository: okonet/lint-staged (js)

Issue:
Support commands which throw error on `--` argument
Using certain tools (e.g. Flow v0.48.0: `flow focus-check`) will not run correctly if they don't understand/expect an argument `--`.

**Steps to reproduce**
1. `git init`
1. `npm init -y`
1. `yarn add lint-staged flow-bin@0.48.0`
1. `flow init`
1. `.lintstagedrc`:
    ```json
    {
      "*.js": ["flow focus-check"]
    }
    ```
1. `index.js`:
    ```js
    // @flow
    ```
1. `git add .`
1. `lint-staged`

**Actual result**
The `flow focus-check` command will fail via `lint-staged`

**Expected result**
The `flow focus-check` command should pass, like it does when being run externally like: `flow focus-check index.js`

Pull request description:
feat: Skip '--' argument for non-npm commands
Closes #195 

BREAKING CHANGE: This might affect existing setups which depend on the `--` argument.

Patch:
diff --git a/README.md b/README.md
index b478684..0fcf77d 100644
--- a/README.md
+++ b/README.md
@@ -76,7 +76,7 @@ Should be an object where each value is a command to run and its key is a glob p
 
 ```json
 {
-	"*": "my-task"
+  "*": "my-task"
 }
 ```
 
@@ -105,14 +105,14 @@ It is possible to run linters for certain paths only by using [minimatch](https:
 
 ```js
 {
-	// .js files anywhere in the project
-	"*.js": "eslint",
-	// .js files anywhere in the project
-	"**/*.js": "eslint",
-	// .js file in the src directory
-	"src/*.js": "eslint",
-	// .js file anywhere within and below the src directory
-	"src/**/*.js": "eslint",
+  // .js files anywhere in the project
+  "*.js": "eslint",
+  // .js files anywhere in the project
+  "**/*.js": "eslint",
+  // .js file in the src directory
+  "src/*.js": "eslint",
+  // .js file anywhere within and below the src directory
+  "src/**/*.js": "eslint",
 }
 ```
 
@@ -126,7 +126,7 @@ Supported are both local npm scripts (`npm run-script`), or any executables inst
 
 ```json
 {
-	"*.js": "eslint --fix"
+  "*.js": "eslint --fix"
 }
 ```
 
@@ -140,7 +140,7 @@ Tools like ESLint/TSLint or stylefmt can reformat your code according to an appr
 
 ```json
 {
-	"*.js": ["eslint --fix", "git add"]
+  "*.js": ["eslint --fix", "git add"]
 }
 ```
 
@@ -180,7 +180,7 @@ All examples assuming you’ve already set up lint-staged and husky in the `pack
 
 ```json
 {
-	"*.{js,jsx}": "eslint"
+  "*.{js,jsx}": "eslint"
 }
 ```
 
@@ -188,7 +188,7 @@ All examples assuming you’ve already set up lint-staged and husky in the `pack
 
 ```json
 {
-	"*.js": ["eslint --fix", "git add"]
+  "*.js": ["eslint --fix", "git add"]
 }
 ```
 
@@ -199,13 +199,13 @@ This will run `eslint --fix` and automatically add changes to the commit. Please
 
 ```json
 {
-	"*.{js,jsx}": ["prettier --parser flow --write", "git add"]
+  "*.{js,jsx}": ["prettier --parser flow --write", "git add"]
 }
 ```
 
 ```json
 {
-	"*.{ts,tsx}": ["prettier --parser typescript --write", "git add"]
+  "*.{ts,tsx}": ["prettier --parser typescript --write", "git add"]
 }
 ```
 
@@ -214,8 +214,8 @@ This will run `eslint --fix` and automatically add changes to the commit. Please
 
 ```json
 {
-	"*.css": "stylelint",
-	"*.scss": "stylelint --syntax=scss"
+  "*.css": "stylelint",
+  "*.scss": "stylelint --syntax=scss"
 }
 ```
 
@@ -223,7 +223,7 @@ This will run `eslint --fix` and automatically add changes to the commit. Please
 
 ```json
 {
-	"*.scss": ["stylefmt", "stylelint --syntax scss", "git add"]
+  "*.scss": ["stylefmt", "stylelint --syntax scss", "git add"]
 }
 ```
 
@@ -231,10 +231,10 @@ This will run `eslint --fix` and automatically add changes to the commit. Please
 
 ```json
 {
-	"*.scss": [
-	  "postcss --config path/to/your/config --replace",
-	  "stylelint",
-	  "git add"
-	]
+  "*.scss": [
+    "postcss --config path/to/your/config --replace",
+    "stylelint",
+    "git add"
+  ]
 }
 ```
diff --git a/src/runScript.js b/src/runScript.js
index 7369713..1b8cb9e 100644
--- a/src/runScript.js
+++ b/src/runScript.js
@@ -27,6 +27,9 @@ module.exports = function runScript(commands, pathsToLint, packageJson, options)
             try {
                 const res = findBin(linter, packageJson, options)
 
+                const separatorArgs = /npm(\.exe)?$/i.test(res.bin)
+                    ? ['--'] : [];
+
                 // Only use gitDir as CWD if we are using the git binary
                 // e.g `npm` should run tasks in the actual CWD
                 const execaOptions =
@@ -35,7 +38,7 @@ module.exports = function runScript(commands, pathsToLint, packageJson, options)
 
                 const errors = []
                 const mapper = (pathsChunk) => {
-                    const args = res.args.concat(['--'], pathsChunk)
+                    const args = res.args.concat(separatorArgs, pathsChunk)
 
                     return execa(res.bin, args, Object.assign({}, execaOptions))
                         /* If we don't catch, pMap will terminate on first rejection */
@@ -67,4 +70,3 @@ ${ errStderr }`)
         }
     }))
 }
-


Test patch:
diff --git a/test/runScript-mock-findBin.spec.js b/test/runScript-mock-findBin.spec.js
index dc7f5f8..9d8eb0d 100644
--- a/test/runScript-mock-findBin.spec.js
+++ b/test/runScript-mock-findBin.spec.js
@@ -60,8 +60,7 @@ describe.only('runScript with absolute paths', () => {
         await taskPromise
         expect(mockFn.mock.calls.length).toEqual(1)
         expect(mockFn.mock.calls[0][0]).toMatch('/usr/local/bin/git')
-        expect(mockFn.mock.calls[0][1]).toEqual(['add', '--', 'test.js'])
+        expect(mockFn.mock.calls[0][1]).toEqual(['add', 'test.js'])
         expect(mockFn.mock.calls[0][2]).toEqual({ cwd: '../' })
     })
 })
-
diff --git a/test/runScript.spec.js b/test/runScript.spec.js
index 4d5a008..f089019 100644
--- a/test/runScript.spec.js
+++ b/test/runScript.spec.js
@@ -105,14 +105,14 @@ describe('runScript', () => {
         await taskPromise
         expect(mockFn.mock.calls.length).toEqual(1)
         expect(mockFn.mock.calls[0][0]).toContain('node')
-        expect(mockFn.mock.calls[0][1]).toEqual(['--arg=true', './myscript.js', '--', 'test.js'])
+        expect(mockFn.mock.calls[0][1]).toEqual(['--arg=true', './myscript.js', 'test.js'])
 
         taskPromise = res[1].task()
         expect(taskPromise).toBeAPromise()
         await taskPromise
         expect(mockFn.mock.calls.length).toEqual(2)
         expect(mockFn.mock.calls[1][0]).toContain('git')
-        expect(mockFn.mock.calls[1][1]).toEqual(['add', '--', 'test.js'])
+        expect(mockFn.mock.calls[1][1]).toEqual(['add', 'test.js'])
     })
 
     it('should pass cwd to execa if gitDir option is set for non-npm tasks', async () => {
@@ -135,7 +135,7 @@ describe('runScript', () => {
         await taskPromise
         expect(mockFn.mock.calls.length).toEqual(2)
         expect(mockFn.mock.calls[1][0]).toMatch(/git$/)
-        expect(mockFn.mock.calls[1][1]).toEqual(['add', '--', 'test.js'])
+        expect(mockFn.mock.calls[1][1]).toEqual(['add', 'test.js'])
         expect(mockFn.mock.calls[1][2]).toEqual({ cwd: '../' })
     })
 
@@ -151,7 +151,7 @@ describe('runScript', () => {
         await taskPromise
         expect(mockFn.mock.calls.length).toEqual(1)
         expect(mockFn.mock.calls[0]).toEqual(
-          ['jest', ['--', 'test.js'], {}]
+          ['jest', ['test.js'], {}]
         )
     })
 
@@ -204,4 +204,3 @@ ${ linteErr.stderr }`)
         }
     })
 })
-