lint-staged 16.1.1 → 16.1.3
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 +1 -1
- package/lib/chunkFiles.js +5 -1
- package/lib/gitWorkflow.js +17 -2
- package/lib/resolveGitRepo.js +29 -29
- package/lib/runAll.js +0 -2
- package/lib/searchConfigs.js +26 -18
- package/package.json +17 -14
package/README.md
CHANGED
|
@@ -304,7 +304,7 @@ Supported are any executables installed locally or globally via `npm` as well as
|
|
|
304
304
|
|
|
305
305
|
> Using globally installed scripts is discouraged, since lint-staged may not work for someone who doesn't have it installed.
|
|
306
306
|
|
|
307
|
-
`lint-staged` uses [
|
|
307
|
+
`lint-staged` uses [nano-spawn](https://github.com/sindresorhus/nano-spawn?tab=readme-ov-file#optionspreferlocal) to locate locally installed scripts. So in your `.lintstagedrc` you can write:
|
|
308
308
|
|
|
309
309
|
```json
|
|
310
310
|
{
|
package/lib/chunkFiles.js
CHANGED
|
@@ -52,7 +52,11 @@ export const chunkFiles = ({ files, baseDir, maxArgLength = null, relative = fal
|
|
|
52
52
|
return [normalizedFiles] // wrap in an array to return a single chunk
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
/** Calculate total character length of all filepaths, with added spaces in between */
|
|
56
|
+
const fileListLength =
|
|
57
|
+
normalizedFiles.reduce((sum, file) => sum + file.filepath.length, 0) +
|
|
58
|
+
Math.max(normalizedFiles.length - 1, 0)
|
|
59
|
+
|
|
56
60
|
debugLog(
|
|
57
61
|
`Resolved an argument string length of ${fileListLength} characters from ${normalizedFiles.length} files`
|
|
58
62
|
)
|
package/lib/gitWorkflow.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import fs from 'node:fs/promises'
|
|
1
2
|
import path from 'node:path'
|
|
2
3
|
|
|
3
4
|
import debug from 'debug'
|
|
@@ -279,8 +280,22 @@ export class GitWorkflow {
|
|
|
279
280
|
// These additions per chunk are run "serially" to prevent race conditions.
|
|
280
281
|
// Git add creates a lockfile in the repo causing concurrent operations to fail.
|
|
281
282
|
for (const files of this.matchedFileChunks) {
|
|
282
|
-
|
|
283
|
-
|
|
283
|
+
const accessCheckedFiles = await Promise.allSettled(
|
|
284
|
+
files.map(async (f) => {
|
|
285
|
+
if (f.status === 'D') {
|
|
286
|
+
await fs.access(f.filepath)
|
|
287
|
+
return f.filepath // File is no longer deleted and can be added
|
|
288
|
+
} else {
|
|
289
|
+
return f.filepath
|
|
290
|
+
}
|
|
291
|
+
})
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
const addableFiles = accessCheckedFiles.flatMap((r) =>
|
|
295
|
+
r.status === 'fulfilled' ? [r.value] : []
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
await this.execGit(['add', '--', ...addableFiles])
|
|
284
299
|
}
|
|
285
300
|
|
|
286
301
|
debugLog('Done adding task modifications to index!')
|
package/lib/resolveGitRepo.js
CHANGED
|
@@ -8,53 +8,53 @@ import { normalizePath } from './normalizePath.js'
|
|
|
8
8
|
const debugLog = debug('lint-staged:resolveGitRepo')
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* @example ".git"
|
|
11
|
+
* Relative path up to the repo top-level directory
|
|
12
|
+
* @example "../"
|
|
14
13
|
*/
|
|
15
|
-
const
|
|
16
|
-
/**
|
|
17
|
-
* Absolute repo top-level directory
|
|
18
|
-
*
|
|
19
|
-
* @example <caption>Git on macOS</caption>
|
|
20
|
-
* "/Users/iiro/Documents/git/lint-staged"
|
|
21
|
-
*
|
|
22
|
-
* @example <caption>Git for Windows</caption>
|
|
23
|
-
* "C:\Users\iiro\Documents\git\lint-staged"
|
|
24
|
-
*
|
|
25
|
-
* @example <caption>Git installed with MSYS2, this doesn't work when used as CWD with Node.js child_process</caption>
|
|
26
|
-
* "/c/Users/iiro/Documents/git/lint-staged"
|
|
27
|
-
*/
|
|
28
|
-
const topLevelPromise = execGit(['rev-parse', '--show-toplevel'], { cwd })
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Absolute .git directory, similar to top-level
|
|
32
|
-
*
|
|
33
|
-
* @example "/Users/iiro/Documents/git/lint-staged/.git"
|
|
34
|
-
*/
|
|
35
|
-
const absoluteGitDirPromise = execGit(['rev-parse', '--absolute-git-dir'], { cwd })
|
|
14
|
+
const CDUP = '--show-cdup'
|
|
36
15
|
|
|
37
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Absolute repo top-level directory
|
|
18
|
+
*
|
|
19
|
+
* @example <caption>Git on macOS</caption>
|
|
20
|
+
* "/Users/iiro/Documents/git/lint-staged"
|
|
21
|
+
*
|
|
22
|
+
* @example <caption>Git for Windows</caption>
|
|
23
|
+
* "C:\Users\iiro\Documents\git\lint-staged"
|
|
24
|
+
*
|
|
25
|
+
* @example <caption>Git installed with MSYS2, this doesn't work when used as CWD with Node.js child_process</caption>
|
|
26
|
+
* "/c/Users/iiro/Documents/git/lint-staged"
|
|
27
|
+
*/
|
|
28
|
+
const TOPLEVEL = '--show-toplevel'
|
|
38
29
|
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Absolute .git directory, similar to top-level
|
|
32
|
+
*
|
|
33
|
+
* @example "/Users/iiro/Documents/git/lint-staged/.git"
|
|
34
|
+
*/
|
|
35
|
+
const ABSOLUTE_GIT_DIR = '--absolute-git-dir'
|
|
41
36
|
|
|
42
37
|
/** Resolve git directory and possible submodule paths */
|
|
43
38
|
export const resolveGitRepo = async (cwd = process.cwd()) => {
|
|
44
39
|
try {
|
|
45
40
|
debugLog('Resolving git repo from `%s`', cwd)
|
|
46
41
|
|
|
42
|
+
/** Git rev-parse returns all three flag values on separate lines */
|
|
43
|
+
const revParseOutput = await execGit(['rev-parse', CDUP, TOPLEVEL, ABSOLUTE_GIT_DIR], {
|
|
44
|
+
cwd,
|
|
45
|
+
})
|
|
46
|
+
const [relativeTopLevelDir, topLevel, absoluteGitDir] = revParseOutput.split('\n')
|
|
47
|
+
|
|
47
48
|
// Unset GIT_DIR before running any git operations in case it's pointing to an incorrect location
|
|
48
49
|
debugLog('Unset GIT_DIR (was `%s`)', process.env.GIT_DIR)
|
|
49
50
|
delete process.env.GIT_DIR
|
|
50
51
|
debugLog('Unset GIT_WORK_TREE (was `%s`)', process.env.GIT_WORK_TREE)
|
|
51
52
|
delete process.env.GIT_WORK_TREE
|
|
52
53
|
|
|
53
|
-
const relativeTopLevelDir = await execGit(['rev-parse', '--show-cdup'], { cwd })
|
|
54
54
|
const topLevelDir = normalizePath(path.join(cwd, relativeTopLevelDir))
|
|
55
55
|
debugLog('Resolved git repository top-level directory to be `%s`', topLevelDir)
|
|
56
56
|
|
|
57
|
-
const relativeGitConfigDir =
|
|
57
|
+
const relativeGitConfigDir = path.relative(topLevel, absoluteGitDir)
|
|
58
58
|
const gitConfigDir = normalizePath(path.join(topLevelDir, relativeGitConfigDir))
|
|
59
59
|
debugLog('Resolved git config directory to be `%s`', gitConfigDir)
|
|
60
60
|
|
package/lib/runAll.js
CHANGED
package/lib/searchConfigs.js
CHANGED
|
@@ -15,14 +15,12 @@ const debugLog = debug('lint-staged:searchConfigs')
|
|
|
15
15
|
|
|
16
16
|
const EXEC_GIT = ['ls-files', '-z', '--full-name', '-t']
|
|
17
17
|
|
|
18
|
-
const
|
|
18
|
+
const CONFIG_PATHSPEC = CONFIG_FILE_NAMES.map((f) => `:(glob)**/${f}`)
|
|
19
19
|
|
|
20
20
|
const numberOfLevels = (file) => file.split('/').length
|
|
21
21
|
|
|
22
22
|
const sortDeepestParth = (a, b) => (numberOfLevels(a) > numberOfLevels(b) ? -1 : 1)
|
|
23
23
|
|
|
24
|
-
const isInsideDirectory = (dir) => (file) => file.startsWith(normalizePath(dir))
|
|
25
|
-
|
|
26
24
|
/**
|
|
27
25
|
* Search all config files from the git repository, preferring those inside `cwd`.
|
|
28
26
|
*
|
|
@@ -57,27 +55,37 @@ export const searchConfigs = async (
|
|
|
57
55
|
return { [configPath]: validateConfig(config, filepath, logger) }
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
58
|
+
/** Get all possible config files from git (both cached and uncommitted) */
|
|
59
|
+
const gitListedFiles = await execGit(
|
|
60
|
+
[
|
|
61
|
+
...EXEC_GIT,
|
|
62
|
+
'--cached', // show all tracked files
|
|
63
|
+
'--others', // show untracked files
|
|
64
|
+
'--exclude-standard', // apply standard git exclusions (.gitignore, etc.)
|
|
65
|
+
'--',
|
|
66
|
+
...CONFIG_PATHSPEC,
|
|
67
|
+
],
|
|
68
|
+
{ cwd }
|
|
69
|
+
).then(parseGitZOutput)
|
|
70
|
+
|
|
71
|
+
debugLog('Git listed files matching config files:', gitListedFiles)
|
|
68
72
|
|
|
69
73
|
/** Sort possible config files so that deepest is first */
|
|
70
|
-
const possibleConfigFiles =
|
|
71
|
-
.flatMap(
|
|
74
|
+
const possibleConfigFiles = gitListedFiles
|
|
75
|
+
.flatMap((line) => {
|
|
72
76
|
/**
|
|
73
77
|
* Leave out lines starting with "S " to ignore not-checked-out files in a sparse repo.
|
|
74
78
|
* The "S" status means a tracked file that is "skip-worktree"
|
|
75
79
|
* @see https://git-scm.com/docs/git-ls-files#Documentation/git-ls-files.txt--t
|
|
76
|
-
*/
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
*/
|
|
81
|
+
if (line.startsWith('S ')) {
|
|
82
|
+
return []
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const relativePath = line.replace(/^[HSMRCK?U] /, '')
|
|
86
|
+
const absolutePath = normalizePath(path.join(topLevelDir, relativePath))
|
|
87
|
+
return [absolutePath]
|
|
88
|
+
})
|
|
81
89
|
.sort(sortDeepestParth)
|
|
82
90
|
|
|
83
91
|
debugLog('Found possible config files:', possibleConfigFiles)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lint-staged",
|
|
3
|
-
"version": "16.1.
|
|
3
|
+
"version": "16.1.3",
|
|
4
4
|
"description": "Lint files staged by git",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,7 +28,10 @@
|
|
|
28
28
|
"lint-staged": "bin/lint-staged.js"
|
|
29
29
|
},
|
|
30
30
|
"exports": {
|
|
31
|
-
".":
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./lib/index.d.ts",
|
|
33
|
+
"default": "./lib/index.js"
|
|
34
|
+
},
|
|
32
35
|
"./bin": "./bin/lint-staged.js",
|
|
33
36
|
"./package.json": "./package.json"
|
|
34
37
|
},
|
|
@@ -51,7 +54,7 @@
|
|
|
51
54
|
"commander": "^14.0.0",
|
|
52
55
|
"debug": "^4.4.1",
|
|
53
56
|
"lilconfig": "^3.1.3",
|
|
54
|
-
"listr2": "^
|
|
57
|
+
"listr2": "^9.0.1",
|
|
55
58
|
"micromatch": "^4.0.8",
|
|
56
59
|
"nano-spawn": "^1.0.2",
|
|
57
60
|
"pidtree": "^0.6.0",
|
|
@@ -60,25 +63,25 @@
|
|
|
60
63
|
},
|
|
61
64
|
"devDependencies": {
|
|
62
65
|
"@changesets/changelog-github": "0.5.1",
|
|
63
|
-
"@changesets/cli": "2.29.
|
|
66
|
+
"@changesets/cli": "2.29.5",
|
|
64
67
|
"@commitlint/cli": "19.8.1",
|
|
65
68
|
"@commitlint/config-conventional": "19.8.1",
|
|
66
|
-
"@eslint/js": "9.
|
|
69
|
+
"@eslint/js": "9.32.0",
|
|
67
70
|
"consolemock": "1.1.0",
|
|
68
|
-
"cross-env": "
|
|
69
|
-
"eslint": "9.
|
|
70
|
-
"eslint-config-prettier": "10.1.
|
|
71
|
-
"eslint-plugin-jest": "
|
|
72
|
-
"eslint-plugin-n": "17.
|
|
73
|
-
"eslint-plugin-prettier": "5.
|
|
71
|
+
"cross-env": "10.0.0",
|
|
72
|
+
"eslint": "9.32.0",
|
|
73
|
+
"eslint-config-prettier": "10.1.8",
|
|
74
|
+
"eslint-plugin-jest": "29.0.1",
|
|
75
|
+
"eslint-plugin-n": "17.21.3",
|
|
76
|
+
"eslint-plugin-prettier": "5.5.3",
|
|
74
77
|
"eslint-plugin-simple-import-sort": "12.1.1",
|
|
75
78
|
"husky": "9.1.7",
|
|
76
|
-
"jest": "30.0.
|
|
79
|
+
"jest": "30.0.5",
|
|
77
80
|
"jest-snapshot-serializer-ansi": "2.2.1",
|
|
78
81
|
"mock-stdin": "1.0.0",
|
|
79
|
-
"prettier": "3.
|
|
82
|
+
"prettier": "3.6.2",
|
|
80
83
|
"semver": "7.7.2",
|
|
81
|
-
"typescript": "5.
|
|
84
|
+
"typescript": "5.9.2"
|
|
82
85
|
},
|
|
83
86
|
"keywords": [
|
|
84
87
|
"lint",
|