lint-staged 12.3.4 → 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 +15 -2
- package/lib/searchConfigs.js +69 -0
- package/package.json +1 -1
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
|
|
|
@@ -121,7 +122,19 @@ export const runAll = async (
|
|
|
121
122
|
|
|
122
123
|
const configGroups = await getConfigGroups({ configObject, configPath, cwd, files }, logger)
|
|
123
124
|
|
|
124
|
-
const
|
|
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
|
|
125
138
|
|
|
126
139
|
// lint-staged 10 will automatically add modifications to index
|
|
127
140
|
// Warn user when their command includes `git add`
|
|
@@ -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
|
+
}
|