lint-staged 12.3.5 → 12.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -713,6 +713,17 @@ Example repo: [sudo-suhas/lint-staged-django-react-demo](https://github.com/sudo
713
713
 
714
714
  </details>
715
715
 
716
+ ### Can I use `lint-staged` with `ng lint`
717
+
718
+ <details>
719
+ <summary>Click to expand</summary>
720
+
721
+ You should not use `ng lint` through _lint-staged_, because it's designed to lint an entire project. Instead, you can add `ng lint` to your git pre-commit hook the same way as you would run lint-staged.
722
+
723
+ See issue [!951](https://github.com/okonet/lint-staged/issues/951) for more details and possible workarounds.
724
+
725
+ </details>
726
+
716
727
  ### How can I ignore files from `.eslintignore`?
717
728
 
718
729
  <details>
@@ -1,7 +1,28 @@
1
- export const getRenderer = ({ debug, quiet }, env = process.env) => {
1
+ const getMainRendererOptions = ({ debug, quiet }, env) => {
2
2
  if (quiet) return { renderer: 'silent' }
3
3
  // Better support for dumb terminals: https://en.wikipedia.org/wiki/Computer_terminal#Dumb_terminals
4
4
  const isDumbTerminal = env.TERM === 'dumb'
5
5
  if (debug || isDumbTerminal || env.NODE_ENV === 'test') return { renderer: 'verbose' }
6
6
  return { renderer: 'update', rendererOptions: { dateFormat: false } }
7
7
  }
8
+
9
+ const getFallbackRenderer = ({ renderer }, { FORCE_COLOR }) => {
10
+ if (renderer === 'silent') {
11
+ return 'silent'
12
+ }
13
+
14
+ // If colors are being forced, then also force non-fallback rendering
15
+ if (Number(FORCE_COLOR) > 0) {
16
+ return renderer
17
+ }
18
+
19
+ return 'verbose'
20
+ }
21
+
22
+ export const getRenderer = (options, env = process.env) => {
23
+ const mainRendererOptions = getMainRendererOptions(options, env)
24
+ return {
25
+ ...mainRendererOptions,
26
+ nonTTYRenderer: getFallbackRenderer(mainRendererOptions, env),
27
+ }
28
+ }
@@ -2,14 +2,17 @@ import { redBright, dim } from 'colorette'
2
2
  import execa from 'execa'
3
3
  import debug from 'debug'
4
4
  import { parseArgsStringToArgv } from 'string-argv'
5
+ import pidTree from 'pidtree'
5
6
 
6
7
  import { error, info } from './figures.js'
7
8
  import { getInitialState } from './state.js'
8
9
  import { TaskError } from './symbols.js'
9
10
 
11
+ const ERROR_CHECK_INTERVAL = 200
12
+
10
13
  const debugLog = debug('lint-staged:resolveTaskFn')
11
14
 
12
- const getTag = ({ code, killed, signal }) => signal || (killed && 'KILLED') || code || 'FAILED'
15
+ const getTag = ({ code, killed, signal }) => (killed && 'KILLED') || signal || code || 'FAILED'
13
16
 
14
17
  /**
15
18
  * Handle task console output.
@@ -43,6 +46,38 @@ const handleOutput = (command, result, ctx, isError = false) => {
43
46
  }
44
47
  }
45
48
 
49
+ /**
50
+ * Interrupts the execution of the execa process that we spawned if
51
+ * another task adds an error to the context.
52
+ *
53
+ * @param {Object} ctx
54
+ * @param {execa.ExecaChildProcess<string>} execaChildProcess
55
+ * @returns {function(): void} Function that clears the interval that
56
+ * checks the context.
57
+ */
58
+ const interruptExecutionOnError = (ctx, execaChildProcess) => {
59
+ let loopIntervalId
60
+
61
+ async function loop() {
62
+ if (ctx.errors.size > 0) {
63
+ clearInterval(loopIntervalId)
64
+
65
+ const ids = await pidTree(execaChildProcess.pid)
66
+ ids.forEach((id) => process.kill(id))
67
+
68
+ // The execa process is killed separately in order
69
+ // to get the `KILLED` status.
70
+ execaChildProcess.kill()
71
+ }
72
+ }
73
+
74
+ loopIntervalId = setInterval(loop, ERROR_CHECK_INTERVAL)
75
+
76
+ return () => {
77
+ clearInterval(loopIntervalId)
78
+ }
79
+ }
80
+
46
81
  /**
47
82
  * Create a error output dependding on process result.
48
83
  *
@@ -101,9 +136,13 @@ export const resolveTaskFn = ({
101
136
  debugLog('execaOptions:', execaOptions)
102
137
 
103
138
  return async (ctx = getInitialState()) => {
104
- const result = await (shell
139
+ const execaChildProcess = shell
105
140
  ? execa.command(isFn ? command : `${command} ${files.join(' ')}`, execaOptions)
106
- : execa(cmd, isFn ? args : args.concat(files), execaOptions))
141
+ : execa(cmd, isFn ? args : args.concat(files), execaOptions)
142
+
143
+ const quitInterruptCheck = interruptExecutionOnError(ctx, execaChildProcess)
144
+ const result = await execaChildProcess
145
+ quitInterruptCheck()
107
146
 
108
147
  if (result.failed || result.killed || result.signal != null) {
109
148
  throw makeErr(command, result, ctx)
package/lib/runAll.js CHANGED
@@ -143,7 +143,6 @@ export const runAll = async (
143
143
  const listrOptions = {
144
144
  ctx,
145
145
  exitOnError: false,
146
- nonTTYRenderer: 'verbose',
147
146
  registerSignalListeners: false,
148
147
  ...getRenderer({ debug, quiet }),
149
148
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lint-staged",
3
- "version": "12.3.5",
3
+ "version": "12.3.8",
4
4
  "description": "Lint files staged by git",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/okonet/lint-staged",
@@ -42,6 +42,7 @@
42
42
  "micromatch": "^4.0.4",
43
43
  "normalize-path": "^3.0.0",
44
44
  "object-inspect": "^1.12.0",
45
+ "pidtree": "^0.5.0",
45
46
  "string-argv": "^0.3.1",
46
47
  "supports-color": "^9.2.1",
47
48
  "yaml": "^1.10.2"