lint-staged 10.2.4 → 10.2.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.
@@ -19,19 +19,20 @@ const MERGE_HEAD = 'MERGE_HEAD'
19
19
  const MERGE_MODE = 'MERGE_MODE'
20
20
  const MERGE_MSG = 'MERGE_MSG'
21
21
 
22
- // In git status, renames are presented as `from` -> `to`.
22
+ // In git status machine output, renames are presented as `to`NUL`from`
23
23
  // When diffing, both need to be taken into account, but in some cases on the `to`.
24
- const RENAME = / -> /
24
+ // eslint-disable-next-line no-control-regex
25
+ const RENAME = /\x00/
25
26
 
26
27
  /**
27
- * From list of files, split renames and flatten into two files `from` -> `to`.
28
+ * From list of files, split renames and flatten into two files `to`NUL`from`.
28
29
  * @param {string[]} files
29
30
  * @param {Boolean} [includeRenameFrom=true] Whether or not to include the `from` renamed file, which is no longer on disk
30
31
  */
31
32
  const processRenames = (files, includeRenameFrom = true) =>
32
33
  files.reduce((flattened, file) => {
33
34
  if (RENAME.test(file)) {
34
- const [from, to] = file.split(RENAME)
35
+ const [to, from] = file.split(RENAME)
35
36
  if (includeRenameFrom) flattened.push(from)
36
37
  flattened.push(to)
37
38
  } else {
@@ -158,15 +159,20 @@ class GitWorkflow {
158
159
  */
159
160
  async getPartiallyStagedFiles() {
160
161
  debug('Getting partially staged files...')
161
- const status = await this.execGit(['status', '--porcelain'])
162
+ const status = await this.execGit(['status', '-z'])
163
+ /**
164
+ * See https://git-scm.com/docs/git-status#_short_format
165
+ * Entries returned in machine format are separated by a NUL character.
166
+ * The first letter of each entry represents current index status,
167
+ * and second the working tree. Index and working tree status codes are
168
+ * separated from the file name by a space. If an entry includes a
169
+ * renamed file, the file names are separated by a NUL character
170
+ * (e.g. `to`\0`from`)
171
+ */
162
172
  const partiallyStaged = status
163
- .split('\n')
173
+ // eslint-disable-next-line no-control-regex
174
+ .split(/\x00(?=[ AMDRCU?!]{2} |$)/)
164
175
  .filter((line) => {
165
- /**
166
- * See https://git-scm.com/docs/git-status#_short_format
167
- * The first letter of the line represents current index status,
168
- * and second the working tree
169
- */
170
176
  const [index, workingTree] = line
171
177
  return index !== ' ' && workingTree !== ' ' && index !== '?' && workingTree !== '?'
172
178
  })
@@ -1,9 +1,27 @@
1
1
  'use strict'
2
2
 
3
+ const cliTruncate = require('cli-truncate')
4
+ const debug = require('debug')('lint-staged:make-cmd-tasks')
5
+
3
6
  const resolveTaskFn = require('./resolveTaskFn')
4
7
  const { createError } = require('./validateConfig')
5
8
 
6
- const debug = require('debug')('lint-staged:make-cmd-tasks')
9
+ const STDOUT_COLUMNS_DEFAULT = 80
10
+
11
+ const listrPrefixLength = {
12
+ update: ` X `.length, // indented task title where X is a checkmark or a cross (failure)
13
+ verbose: `[STARTED] `.length, // verbose renderer uses 7-letter STARTED/SUCCESS prefixes
14
+ }
15
+
16
+ /**
17
+ * Get length of title based on the number of available columns prefix length
18
+ * @param {string} renderer The name of the Listr renderer
19
+ * @returns {number}
20
+ */
21
+ const getTitleLength = (renderer, columns = process.stdout.columns) => {
22
+ const prefixLength = listrPrefixLength[renderer] || 0
23
+ return (columns || STDOUT_COLUMNS_DEFAULT) - prefixLength
24
+ }
7
25
 
8
26
  /**
9
27
  * Creates and returns an array of listr tasks which map to the given commands.
@@ -12,10 +30,11 @@ const debug = require('debug')('lint-staged:make-cmd-tasks')
12
30
  * @param {Array<string|Function>|string|Function} options.commands
13
31
  * @param {Array<string>} options.files
14
32
  * @param {string} options.gitDir
33
+ * @param {string} options.renderer
15
34
  * @param {Boolean} shell
16
35
  * @param {Boolean} verbose
17
36
  */
18
- module.exports = async function makeCmdTasks({ commands, files, gitDir, shell, verbose }) {
37
+ const makeCmdTasks = async ({ commands, files, gitDir, renderer, shell, verbose }) => {
19
38
  debug('Creating listr tasks for commands %o', commands)
20
39
  const commandArray = Array.isArray(commands) ? commands : [commands]
21
40
  const cmdTasks = []
@@ -28,32 +47,26 @@ module.exports = async function makeCmdTasks({ commands, files, gitDir, shell, v
28
47
  const resolvedArray = Array.isArray(resolved) ? resolved : [resolved] // Wrap non-array command as array
29
48
 
30
49
  for (const command of resolvedArray) {
31
- let title = isFn ? '[Function]' : command
32
-
33
- if (isFn) {
34
- // If the function linter didn't return string | string[] it won't work
35
- // Do the validation here instead of `validateConfig` to skip evaluating the function multiple times
36
- if (typeof command !== 'string') {
37
- throw new Error(
38
- createError(
39
- title,
40
- 'Function task should return a string or an array of strings',
41
- resolved
42
- )
50
+ // If the function linter didn't return string | string[] it won't work
51
+ // Do the validation here instead of `validateConfig` to skip evaluating the function multiple times
52
+ if (isFn && typeof command !== 'string') {
53
+ throw new Error(
54
+ createError(
55
+ '[Function]',
56
+ 'Function task should return a string or an array of strings',
57
+ resolved
43
58
  )
44
- }
45
-
46
- const [startOfFn] = command.split(' ')
47
- title += ` ${startOfFn} ...` // Append function name, like `[Function] eslint ...`
59
+ )
48
60
  }
49
61
 
50
- cmdTasks.push({
51
- title,
52
- command,
53
- task: resolveTaskFn({ command, files, gitDir, isFn, shell, verbose }),
54
- })
62
+ // Truncate title to single line based on renderer
63
+ const title = cliTruncate(command, getTitleLength(renderer))
64
+ const task = resolveTaskFn({ command, files, gitDir, isFn, shell, verbose })
65
+ cmdTasks.push({ title, command, task })
55
66
  }
56
67
  }
57
68
 
58
69
  return cmdTasks
59
70
  }
71
+
72
+ module.exports = makeCmdTasks
package/lib/runAll.js CHANGED
@@ -119,6 +119,7 @@ const runAll = async (
119
119
  ctx,
120
120
  exitOnError: false,
121
121
  nonTTYRenderer: 'verbose',
122
+ registerSignalListeners: false,
122
123
  ...getRenderer({ debug, quiet }),
123
124
  }
124
125
 
@@ -136,6 +137,7 @@ const runAll = async (
136
137
  commands: task.commands,
137
138
  files: task.fileList,
138
139
  gitDir,
140
+ renderer: listrOptions.renderer,
139
141
  shell,
140
142
  verbose,
141
143
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lint-staged",
3
- "version": "10.2.4",
3
+ "version": "10.2.8",
4
4
  "description": "Lint files staged by git",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/okonet/lint-staged",
@@ -33,6 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "chalk": "^4.0.0",
36
+ "cli-truncate": "2.1.0",
36
37
  "commander": "^5.1.0",
37
38
  "cosmiconfig": "^6.0.0",
38
39
  "debug": "^4.1.1",
@@ -62,7 +63,6 @@
62
63
  "husky": "^4.2.5",
63
64
  "jest": "^26.0.1",
64
65
  "jest-snapshot-serializer-ansi": "^1.0.0",
65
- "nanoid": "^3.1.7",
66
66
  "prettier": "^2.0.5"
67
67
  },
68
68
  "config": {