Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
refactor: use execa's shell option to run commands
BREAKING CHANGE: Local commands are no longer resolved by lint-staged, but execa will do this instead. In effect, there are no longer pretty error messages when commands are not found.
  • Loading branch information
iiroj authored and okonet committed Jul 1, 2019
1 parent d3f6475 commit bed9127
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 303 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -214,7 +214,7 @@ Supported are any executables installed locally or globally via `npm` as well as

> Using globally installed scripts is discouraged, since lint-staged may not work for someone who doesn’t have it installed.
`lint-staged` is using [npm-which](https://github.com/timoxley/npm-which) to locate locally installed scripts. So in your `.lintstagedrc` you can write:
`lint-staged` uses [execa](https://github.com/sindresorhus/execa#preferlocal) to locate locally installed scripts. So in your `.lintstagedrc` you can write:

```json
{
Expand Down
4 changes: 1 addition & 3 deletions package.json
Expand Up @@ -33,17 +33,15 @@
"debug": "^3.1.0",
"dedent": "^0.7.0",
"del": "^4.1.1",
"execa": "^1.0.0",
"execa": "^2.0.1",
"is-glob": "^4.0.0",
"listr": "^0.14.2",
"listr-update-renderer": "^0.5.0",
"lodash": "^4.17.11",
"log-symbols": "^2.2.0",
"micromatch": "^3.1.8",
"npm-which": "^3.0.1",
"path-is-inside": "^1.0.2",
"please-upgrade-node": "^3.0.2",
"string-argv": "^0.0.2",
"stringify-object": "^3.2.2",
"yup": "^0.27.0"
},
Expand Down
46 changes: 0 additions & 46 deletions src/checkPkgScripts.js

This file was deleted.

54 changes: 0 additions & 54 deletions src/findBin.js

This file was deleted.

32 changes: 12 additions & 20 deletions src/resolveTaskFn.js
Expand Up @@ -5,25 +5,19 @@ const dedent = require('dedent')
const execa = require('execa')
const symbols = require('log-symbols')

const findBin = require('./findBin')

const debug = require('debug')('lint-staged:task')

/**
* Execute the given linter binary with arguments using execa and
* Execute the given linter cmd using execa and
* return the promise.
*
* @param {string} bin
* @param {Array<string>} args
* @param {Object} execaOptions
* @param {string} cmd
* @return {Promise} child_process
*/
function execLinter(bin, args, execaOptions) {
debug('bin:', bin)
debug('args: %O', args)
debug('opts: %o', execaOptions)

return execa(bin, args, { ...execaOptions })
const execLinter = (cmd, execaOptions = {}) => {
debug('cmd:', cmd)
debug('execaOptions:', execaOptions)
return execa(cmd, execaOptions)
}

const successMsg = linter => `${symbols.success} ${linter} passed!`
Expand Down Expand Up @@ -84,7 +78,7 @@ function makeErr(linter, result, context = {}) {
* @returns {function(): Promise<Array<string>>}
*/
module.exports = function resolveTaskFn(options) {
const { linter, gitDir, pathsToLint } = options
const { gitDir, linter, pathsToLint } = options

// If `linter` is a function, it should return a string when evaluated with `pathsToLint`.
// Else, it's a already a string
Expand All @@ -94,20 +88,18 @@ module.exports = function resolveTaskFn(options) {
const linters = Array.isArray(linterString) ? linterString : [linterString]

const tasks = linters.map(command => {
const { bin, args } = findBin(command)

// If `linter` is a function, args already include `pathsToLint`.
const argsWithPaths = fnLinter ? args : args.concat(pathsToLint)
// If `linter` is a function, cmd already includes `pathsToLint`.
const cmdWithPaths = fnLinter ? command : `${command} ${pathsToLint.join(' ')}`

const execaOptions = { reject: false }
// Only use gitDir as CWD if we are using the git binary
// e.g `npm` should run tasks in the actual CWD
if (/git(\.exe)?$/i.test(bin) && gitDir !== process.cwd()) {
const execaOptions = { preferLocal: true, reject: false, shell: true }
if (/^git(\.exe)?/i.test(command) && gitDir !== process.cwd()) {
execaOptions.cwd = gitDir
}

return ctx =>
execLinter(bin, argsWithPaths, execaOptions).then(result => {
execLinter(cmdWithPaths, execaOptions).then(result => {
if (result.failed || result.killed || result.signal != null) {
throw makeErr(linter, result, ctx)
}
Expand Down
19 changes: 0 additions & 19 deletions test/__snapshots__/checkPkgScripts.spec.js.snap

This file was deleted.

10 changes: 0 additions & 10 deletions test/__snapshots__/findBin.spec.js.snap

This file was deleted.

50 changes: 0 additions & 50 deletions test/checkPkgScripts.spec.js

This file was deleted.

56 changes: 0 additions & 56 deletions test/findBin.spec.js

This file was deleted.

4 changes: 2 additions & 2 deletions test/makeCmdTasks.spec.js
Expand Up @@ -37,11 +37,11 @@ describe('makeCmdTasks', () => {
expect(taskPromise).toBeInstanceOf(Promise)
await taskPromise
expect(execa).toHaveBeenCalledTimes(1)
expect(execa).lastCalledWith('test', ['test.js'], { reject: false })
expect(execa).lastCalledWith('test test.js', { preferLocal: true, reject: false, shell: true })
taskPromise = linter2.task()
expect(taskPromise).toBeInstanceOf(Promise)
await taskPromise
expect(execa).toHaveBeenCalledTimes(2)
expect(execa).lastCalledWith('test2', ['test.js'], { reject: false })
expect(execa).lastCalledWith('test2 test.js', { preferLocal: true, reject: false, shell: true })
})
})

0 comments on commit bed9127

Please sign in to comment.