lint-staged 12.3.2 → 12.3.5
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/lib/getConfigGroups.js +0 -7
- package/lib/getStagedFiles.js +2 -9
- package/lib/loadConfig.js +1 -1
- package/lib/parseGitZOutput.js +9 -0
- package/lib/runAll.js +34 -7
- package/lib/searchConfigs.js +69 -0
- package/package.json +5 -2
package/lib/getConfigGroups.js
CHANGED
|
@@ -99,13 +99,6 @@ export const getConfigGroups = async (
|
|
|
99
99
|
// Discover configs from the base directory of each file
|
|
100
100
|
await Promise.all(Object.entries(filesByDir).map(([dir, files]) => searchConfig(dir, files)))
|
|
101
101
|
|
|
102
|
-
// Throw if no configurations were found
|
|
103
|
-
if (Object.keys(configGroups).length === 0) {
|
|
104
|
-
debugLog('Found no config groups!')
|
|
105
|
-
logger.error(`${ConfigNotFoundError.message}.`)
|
|
106
|
-
throw ConfigNotFoundError
|
|
107
|
-
}
|
|
108
|
-
|
|
109
102
|
debugLog('Grouped staged files into %d groups!', Object.keys(configGroups).length)
|
|
110
103
|
|
|
111
104
|
return configGroups
|
package/lib/getStagedFiles.js
CHANGED
|
@@ -3,6 +3,7 @@ import path from 'path'
|
|
|
3
3
|
import normalize from 'normalize-path'
|
|
4
4
|
|
|
5
5
|
import { execGit } from './execGit.js'
|
|
6
|
+
import { parseGitZOutput } from './parseGitZOutput.js'
|
|
6
7
|
|
|
7
8
|
export const getStagedFiles = async ({ cwd = process.cwd() } = {}) => {
|
|
8
9
|
try {
|
|
@@ -14,15 +15,7 @@ export const getStagedFiles = async ({ cwd = process.cwd() } = {}) => {
|
|
|
14
15
|
|
|
15
16
|
if (!lines) return []
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
// remove the last occurrence of `\u0000` before splitting
|
|
19
|
-
return (
|
|
20
|
-
lines
|
|
21
|
-
// eslint-disable-next-line no-control-regex
|
|
22
|
-
.replace(/\u0000$/, '')
|
|
23
|
-
.split('\u0000')
|
|
24
|
-
.map((file) => normalize(path.resolve(cwd, file)))
|
|
25
|
-
)
|
|
18
|
+
return parseGitZOutput(lines).map((file) => normalize(path.resolve(cwd, file)))
|
|
26
19
|
} catch {
|
|
27
20
|
return null
|
|
28
21
|
}
|
package/lib/loadConfig.js
CHANGED
|
@@ -13,7 +13,7 @@ const debugLog = debug('lint-staged:loadConfig')
|
|
|
13
13
|
* The list of files `lint-staged` will read configuration
|
|
14
14
|
* from, in the declared order.
|
|
15
15
|
*/
|
|
16
|
-
const searchPlaces = [
|
|
16
|
+
export const searchPlaces = [
|
|
17
17
|
'package.json',
|
|
18
18
|
'.lintstagedrc',
|
|
19
19
|
'.lintstagedrc.json',
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return array of strings split from the output of `git <something> -z`.
|
|
3
|
+
* With `-z`, git prints `fileA\u0000fileB\u0000fileC\u0000` so we need to
|
|
4
|
+
* remove the last occurrence of `\u0000` before splitting
|
|
5
|
+
*/
|
|
6
|
+
export const parseGitZOutput = (input) =>
|
|
7
|
+
input
|
|
8
|
+
.replace(/\u0000$/, '') // eslint-disable-line no-control-regex
|
|
9
|
+
.split('\u0000')
|
package/lib/runAll.js
CHANGED
|
@@ -35,7 +35,8 @@ import {
|
|
|
35
35
|
restoreOriginalStateSkipped,
|
|
36
36
|
restoreUnstagedChangesSkipped,
|
|
37
37
|
} from './state.js'
|
|
38
|
-
import { GitRepoError, GetStagedFilesError, GitError } from './symbols.js'
|
|
38
|
+
import { GitRepoError, GetStagedFilesError, GitError, ConfigNotFoundError } from './symbols.js'
|
|
39
|
+
import { searchConfigs } from './searchConfigs.js'
|
|
39
40
|
|
|
40
41
|
const debugLog = debug('lint-staged:runAll')
|
|
41
42
|
|
|
@@ -80,7 +81,8 @@ export const runAll = async (
|
|
|
80
81
|
debugLog('Running all linter scripts...')
|
|
81
82
|
|
|
82
83
|
// Resolve relative CWD option
|
|
83
|
-
|
|
84
|
+
const hasExplicitCwd = !!cwd
|
|
85
|
+
cwd = hasExplicitCwd ? path.resolve(cwd) : process.cwd()
|
|
84
86
|
debugLog('Using working directory `%s`', cwd)
|
|
85
87
|
|
|
86
88
|
const ctx = getInitialState({ quiet })
|
|
@@ -120,6 +122,20 @@ export const runAll = async (
|
|
|
120
122
|
|
|
121
123
|
const configGroups = await getConfigGroups({ configObject, configPath, cwd, files }, logger)
|
|
122
124
|
|
|
125
|
+
const hasExplicitConfig = configObject || configPath
|
|
126
|
+
const foundConfigs = hasExplicitConfig ? null : await searchConfigs(gitDir, logger)
|
|
127
|
+
const numberOfConfigs = hasExplicitConfig ? 1 : Object.keys(foundConfigs).length
|
|
128
|
+
|
|
129
|
+
// Throw if no configurations were found
|
|
130
|
+
if (numberOfConfigs === 0) {
|
|
131
|
+
ctx.errors.add(ConfigNotFoundError)
|
|
132
|
+
throw createError(ctx, ConfigNotFoundError)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
debugLog('Found %d configs:\n%O', numberOfConfigs, foundConfigs)
|
|
136
|
+
|
|
137
|
+
const hasMultipleConfigs = numberOfConfigs > 1
|
|
138
|
+
|
|
123
139
|
// lint-staged 10 will automatically add modifications to index
|
|
124
140
|
// Warn user when their command includes `git add`
|
|
125
141
|
let hasDeprecatedGitAdd = false
|
|
@@ -138,21 +154,25 @@ export const runAll = async (
|
|
|
138
154
|
const matchedFiles = new Set()
|
|
139
155
|
|
|
140
156
|
for (const [configPath, { config, files }] of Object.entries(configGroups)) {
|
|
157
|
+
const relativeConfig = normalize(path.relative(cwd, configPath))
|
|
141
158
|
const stagedFileChunks = chunkFiles({ baseDir: gitDir, files, maxArgLength, relative })
|
|
142
159
|
|
|
160
|
+
// Use actual cwd if it's specified, or there's only a single config file.
|
|
161
|
+
// Otherwise use the directory of the config file for each config group,
|
|
162
|
+
// to make sure tasks are separated from each other.
|
|
163
|
+
const groupCwd = hasMultipleConfigs && !hasExplicitCwd ? path.dirname(configPath) : cwd
|
|
164
|
+
|
|
143
165
|
const chunkCount = stagedFileChunks.length
|
|
144
166
|
if (chunkCount > 1) {
|
|
145
167
|
debugLog('Chunked staged files from `%s` into %d part', configPath, chunkCount)
|
|
146
168
|
}
|
|
147
169
|
|
|
148
170
|
for (const [index, files] of stagedFileChunks.entries()) {
|
|
149
|
-
const relativeConfig = normalize(path.relative(cwd, configPath))
|
|
150
|
-
|
|
151
171
|
const chunkListrTasks = await Promise.all(
|
|
152
|
-
generateTasks({ config, cwd, files, relative }).map((task) =>
|
|
172
|
+
generateTasks({ config, cwd: groupCwd, files, relative }).map((task) =>
|
|
153
173
|
makeCmdTasks({
|
|
154
174
|
commands: task.commands,
|
|
155
|
-
cwd,
|
|
175
|
+
cwd: groupCwd,
|
|
156
176
|
files: task.fileList,
|
|
157
177
|
gitDir,
|
|
158
178
|
renderer: listrOptions.renderer,
|
|
@@ -161,7 +181,14 @@ export const runAll = async (
|
|
|
161
181
|
}).then((subTasks) => {
|
|
162
182
|
// Add files from task to match set
|
|
163
183
|
task.fileList.forEach((file) => {
|
|
164
|
-
|
|
184
|
+
// Make sure relative files are normalized to the
|
|
185
|
+
// group cwd, because other there might be identical
|
|
186
|
+
// relative filenames in the entire set.
|
|
187
|
+
const normalizedFile = path.isAbsolute(file)
|
|
188
|
+
? file
|
|
189
|
+
: normalize(path.join(groupCwd, file))
|
|
190
|
+
|
|
191
|
+
matchedFiles.add(normalizedFile)
|
|
165
192
|
})
|
|
166
193
|
|
|
167
194
|
hasDeprecatedGitAdd =
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** @typedef {import('./index').Logger} Logger */
|
|
2
|
+
|
|
3
|
+
import { basename, join } from 'path'
|
|
4
|
+
|
|
5
|
+
import normalize from 'normalize-path'
|
|
6
|
+
|
|
7
|
+
import { execGit } from './execGit.js'
|
|
8
|
+
import { loadConfig, searchPlaces } from './loadConfig.js'
|
|
9
|
+
import { parseGitZOutput } from './parseGitZOutput.js'
|
|
10
|
+
import { validateConfig } from './validateConfig.js'
|
|
11
|
+
|
|
12
|
+
const EXEC_GIT = ['ls-files', '-z', '--full-name']
|
|
13
|
+
|
|
14
|
+
const filterPossibleConfigFiles = (file) => searchPlaces.includes(basename(file))
|
|
15
|
+
|
|
16
|
+
const numberOfLevels = (file) => file.split('/').length
|
|
17
|
+
|
|
18
|
+
const sortDeepestParth = (a, b) => (numberOfLevels(a) > numberOfLevels(b) ? -1 : 1)
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Search all config files from the git repository
|
|
22
|
+
*
|
|
23
|
+
* @param {string} gitDir
|
|
24
|
+
* @param {Logger} logger
|
|
25
|
+
* @returns {Promise<{ [key: string]: * }>} found configs with filepath as key, and config as value
|
|
26
|
+
*/
|
|
27
|
+
export const searchConfigs = async (gitDir = process.cwd(), logger) => {
|
|
28
|
+
/** Get all possible config files known to git */
|
|
29
|
+
const cachedFiles = parseGitZOutput(await execGit(EXEC_GIT, { cwd: gitDir })).filter(
|
|
30
|
+
filterPossibleConfigFiles
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
/** Get all possible config files from uncommitted files */
|
|
34
|
+
const otherFiles = parseGitZOutput(
|
|
35
|
+
await execGit([...EXEC_GIT, '--others', '--exclude-standard'], { cwd: gitDir })
|
|
36
|
+
).filter(filterPossibleConfigFiles)
|
|
37
|
+
|
|
38
|
+
/** Sort possible config files so that deepest is first */
|
|
39
|
+
const possibleConfigFiles = [...cachedFiles, ...otherFiles]
|
|
40
|
+
.map((file) => join(gitDir, file))
|
|
41
|
+
.map((file) => normalize(file))
|
|
42
|
+
.sort(sortDeepestParth)
|
|
43
|
+
|
|
44
|
+
/** Create object with key as config file, and value as null */
|
|
45
|
+
const configs = possibleConfigFiles.reduce(
|
|
46
|
+
(acc, configPath) => Object.assign(acc, { [configPath]: null }),
|
|
47
|
+
{}
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
/** Load and validate all configs to the above object */
|
|
51
|
+
await Promise.all(
|
|
52
|
+
possibleConfigFiles
|
|
53
|
+
.map((configPath) => loadConfig({ configPath }, logger))
|
|
54
|
+
.map((promise) =>
|
|
55
|
+
promise.then(({ config, filepath }) => {
|
|
56
|
+
if (config) {
|
|
57
|
+
configs[filepath] = validateConfig(config, filepath, logger)
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
/** Get validated configs from the above object, without any `null` values (not found) */
|
|
64
|
+
const foundConfigs = Object.entries(configs)
|
|
65
|
+
.filter(([, value]) => !!value)
|
|
66
|
+
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
|
|
67
|
+
|
|
68
|
+
return foundConfigs
|
|
69
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lint-staged",
|
|
3
|
-
"version": "12.3.
|
|
3
|
+
"version": "12.3.5",
|
|
4
4
|
"description": "Lint files staged by git",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "https://github.com/okonet/lint-staged",
|
|
@@ -18,7 +18,10 @@
|
|
|
18
18
|
},
|
|
19
19
|
"type": "module",
|
|
20
20
|
"bin": "./bin/lint-staged.js",
|
|
21
|
-
"exports":
|
|
21
|
+
"exports": {
|
|
22
|
+
".": "./lib/index.js",
|
|
23
|
+
"./package.json": "./package.json"
|
|
24
|
+
},
|
|
22
25
|
"files": [
|
|
23
26
|
"bin",
|
|
24
27
|
"lib"
|