1 | 'use strict'
|
2 |
|
3 | const chalk = require('chalk')
|
4 | const { parseArgsStringToArgv } = require('string-argv')
|
5 | const dedent = require('dedent')
|
6 | const execa = require('execa')
|
7 | const symbols = require('log-symbols')
|
8 |
|
9 | const debug = require('debug')('lint-staged:task')
|
10 |
|
11 | const successMsg = linter => `${symbols.success} ${linter} passed!`
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | function throwError(message) {
|
23 | const err = new Error()
|
24 | err.privateMsg = `\n\n\n${message}`
|
25 | return err
|
26 | }
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | function makeErr(linter, result, context = {}) {
|
42 | context.taskError = true
|
43 | const { stdout, stderr, killed, signal } = result
|
44 | if (killed || (signal && signal !== '')) {
|
45 | return throwError(
|
46 | `${symbols.warning} ${chalk.yellow(`${linter} was terminated with ${signal}`)}`
|
47 | )
|
48 | }
|
49 | return throwError(dedent`${symbols.error} ${chalk.redBright(
|
50 | `${linter} found some errors. Please fix them and try committing again.`
|
51 | )}
|
52 | ${stdout}
|
53 | ${stderr}
|
54 | `)
|
55 | }
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 | module.exports = function resolveTaskFn({ command, files, gitDir, isFn, relative, shell = false }) {
|
70 | const [cmd, ...args] = parseArgsStringToArgv(command)
|
71 | debug('cmd:', cmd)
|
72 | debug('args:', args)
|
73 |
|
74 | const execaOptions = { preferLocal: true, reject: false, shell }
|
75 | if (relative) {
|
76 | execaOptions.cwd = process.cwd()
|
77 | } else if (/^git(\.exe)?/i.test(cmd) && gitDir !== process.cwd()) {
|
78 |
|
79 |
|
80 | execaOptions.cwd = gitDir
|
81 | }
|
82 | debug('execaOptions:', execaOptions)
|
83 |
|
84 | return async ctx => {
|
85 | const promise = shell
|
86 | ? execa.command(isFn ? command : `${command} ${files.join(' ')}`, execaOptions)
|
87 | : execa(cmd, isFn ? args : args.concat(files), execaOptions)
|
88 | const result = await promise
|
89 |
|
90 | if (result.failed || result.killed || result.signal != null) {
|
91 | throw makeErr(cmd, result, ctx)
|
92 | }
|
93 |
|
94 | return successMsg(cmd)
|
95 | }
|
96 | }
|