Skip to content

Commit

Permalink
feat: invoke eslint as a process to pass arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
Sleavely committed Feb 21, 2023
1 parent 626fd49 commit 675d208
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 14 deletions.
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,25 @@ In your Bitbucket Pipeline or Github Action, instead of `npx eslint .`:
npx eslint-pullrequest
```

It will use your existing ESLint configuration, but will attempt to lint all files in the pull request that have the extensions defined in the `LINTABLE_EXTENSIONS` environment variable. The default value is `.js,.ts,.jsx,.tsx`.
### Arguments

Any flags passed to _eslint-pullrequest_ will be passed to ESLint. See [ESLint CLI reference](https://eslint.org/docs/latest/use/command-line-interface) for inspiration.

For example:

```
npx eslint-pullrequest --format compact
```

### Environment variables

#### `LINTABLE_EXTENSIONS`

_eslint-pullrequest_ will use your existing ESLint configuration, but because of how ESLint file matching works it will only attempt to lint files involved in the pull request that have the extensions defined in the `LINTABLE_EXTENSIONS` environment variable. The default value is `.js,.ts,.jsx,.tsx`.

#### `MAX_EXEC_BUFFER_MB`

The size of the buffer that holds ESLints terminal output. Normally you shouldn't have to change this value unless you have hundreds or thousands of linting errors. The default is `10`.

## License

Expand Down
32 changes: 19 additions & 13 deletions bin/cli.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env node

import { getLintableFiles } from '../src/index'
import { ESLint } from 'eslint'
import execute from '../src/utils/execute'

const {
LINTABLE_EXTENSIONS = '.js,.ts,.jsx,.tsx',
Expand All @@ -11,19 +11,25 @@ const {
const lintableExtensions = LINTABLE_EXTENSIONS.split(',')
const lintableFiles = await getLintableFiles(lintableExtensions)

const eslint = new ESLint()
const results = await eslint.lintFiles(lintableFiles)
const eslintArguments = [
// proxy any command-line arguments we received
...process.argv.slice(2),
...lintableFiles,
]
.filter(Boolean)
.join(' ')

// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
const errorCount = results.reduce((sum, { errorCount }) => { return sum + errorCount }, 0)

if (errorCount) {
const formatter = await eslint.loadFormatter()
const resultText = formatter.format(results)
console.log(resultText)

process.exit(1)
}
await execute(`npx eslint ${eslintArguments}`)
.catch(err => {
// ExecException will have a code
if (err.code) {
console.error(err)
process.exit(err.code)
}
// assume any other output is from eslint
console.log(err.message)
process.exit(1)
})
})().catch(err => {
console.error(err)
process.exit(1)
Expand Down
27 changes: 27 additions & 0 deletions src/utils/execute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { exec } from 'child_process'

const {
MAX_EXEC_BUFFER_MB = '10',
} = process.env

const maxBuffer = 1024 * 1024 * parseFloat(MAX_EXEC_BUFFER_MB)

export default async (command: string): Promise<string> => await new Promise((resolve, reject) => {
exec(`cd "${process.cwd()}" && ${command}`, { shell: 'bash', maxBuffer }, (err, stdout, stderr) => {
if (err) {
// when `command` itself fails its error will be printed to stderr
if (stderr) {
return reject(new Error(stderr))
}
// some apps (eslint) uses stdout even for errors
// lets assume that exitcode 1 means there is a meaningful error from the command itself
if (!err.killed && err.code === 1) {
return reject(new Error(stdout))
}
// when child_process.exec fails the source error will be in `err`
return reject(err)
}

return resolve(stdout)
})
})

0 comments on commit 675d208

Please sign in to comment.