lint-staged 12.4.2 → 13.0.0
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 +37 -2
- package/bin/lint-staged.js +80 -43
- package/lib/chunkFiles.js +1 -1
- package/lib/dynamicImport.js +1 -1
- package/lib/execGit.js +1 -1
- package/lib/file.js +1 -1
- package/lib/generateTasks.js +1 -1
- package/lib/getStagedFiles.js +18 -7
- package/lib/gitWorkflow.js +1 -1
- package/lib/groupFilesByConfig.js +5 -9
- package/lib/index.js +23 -18
- package/lib/messages.js +8 -2
- package/lib/printTaskOutput.js +1 -1
- package/lib/resolveConfig.js +1 -1
- package/lib/resolveGitRepo.js +2 -2
- package/lib/resolveTaskFn.js +2 -2
- package/lib/runAll.js +19 -15
- package/lib/searchConfigs.js +4 -6
- package/lib/validateOptions.js +3 -2
- package/package.json +22 -22
package/README.md
CHANGED
|
@@ -64,6 +64,10 @@ See [Releases](https://github.com/okonet/lint-staged/releases).
|
|
|
64
64
|
|
|
65
65
|
### Migration
|
|
66
66
|
|
|
67
|
+
#### v13
|
|
68
|
+
|
|
69
|
+
- Since `v13.0.0` _lint-staged_ no longer supports Node.js 12. Please upgrade your Node.js version to at least `14.13.1`, or `16.0.0` onward.
|
|
70
|
+
|
|
67
71
|
#### v12
|
|
68
72
|
|
|
69
73
|
- Since `v12.0.0` _lint-staged_ is a pure ESM module, so make sure your Node.js version is at least `12.20.0`, `14.13.1`, or `16.0.0`. Read more about ESM modules from the official [Node.js Documentation site here](https://nodejs.org/api/esm.html#introduction).
|
|
@@ -92,6 +96,10 @@ Options:
|
|
|
92
96
|
-c, --config [path] path to configuration file, or - to read from stdin
|
|
93
97
|
--cwd [path] run all tasks in specific directory, instead of the current
|
|
94
98
|
-d, --debug print additional debug information (default: false)
|
|
99
|
+
--diff [string] override the default "--staged" flag of "git diff" to get list of files. Implies
|
|
100
|
+
"--no-stash".
|
|
101
|
+
--diff-filter [string] override the default "--diff-filter=ACMR" flag of "git diff" to get list of files
|
|
102
|
+
--max-arg-length [number] maximum length of the command-line argument string (default: 0)
|
|
95
103
|
--no-stash disable the backup stash, and do not revert in case of errors
|
|
96
104
|
-q, --quiet disable lint-staged’s own console output (default: false)
|
|
97
105
|
-r, --relative pass relative filepaths to tasks (default: false)
|
|
@@ -111,6 +119,9 @@ Options:
|
|
|
111
119
|
- **`--debug`**: Run in debug mode. When set, it does the following:
|
|
112
120
|
- uses [debug](https://github.com/visionmedia/debug) internally to log additional information about staged files, commands being executed, location of binaries, etc. Debug logs, which are automatically enabled by passing the flag, can also be enabled by setting the environment variable `$DEBUG` to `lint-staged*`.
|
|
113
121
|
- uses [`verbose` renderer](https://github.com/SamVerschueren/listr-verbose-renderer) for `listr`; this causes serial, uncoloured output to the terminal, instead of the default (beautified, dynamic) output.
|
|
122
|
+
- **`--diff`**: By default linters are filtered against all files staged in git, generated from `git diff --staged`. This option allows you to override the `--staged` flag with arbitrary revisions. For example to get a list of changed files between two branches, use `--diff="branch1...branch2"`. You can also read more from about [git diff](https://git-scm.com/docs/git-diff) and [gitrevisions](https://git-scm.com/docs/gitrevisions).
|
|
123
|
+
- **`--diff-filter`**: By default only files that are _added_, _copied_, _modified_, or _renamed_ are included. Use this flag to override the default `ACMR` value with something else: _added_ (`A`), _copied_ (`C`), _deleted_ (`D`), _modified_ (`M`), _renamed_ (`R`), _type changed_ (`T`), _unmerged_ (`U`), _unknown_ (`X`), or _pairing broken_ (`B`). See also the `git diff` docs for [--diff-filter](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203).
|
|
124
|
+
- **`--max-arg-length`**: long commands (a lot of files) are automatically split into multiple chunks when it detects the current shell cannot handle them. Use this flag to override the maximum length of the generated command string.
|
|
114
125
|
- **`--no-stash`**: By default a backup stash will be created before running the tasks, and all task modifications will be reverted in case of an error. This option will disable creating the stash, and instead leave all modifications in the index when aborting the commit.
|
|
115
126
|
- **`--quiet`**: Supress all CLI output, except from tasks.
|
|
116
127
|
- **`--relative`**: Pass filepaths relative to `process.cwd()` (where `lint-staged` runs) to tasks. Default is `false`.
|
|
@@ -594,9 +605,9 @@ const success = await lintStaged({
|
|
|
594
605
|
maxArgLength: null,
|
|
595
606
|
quiet: false,
|
|
596
607
|
relative: false,
|
|
597
|
-
shell: false
|
|
608
|
+
shell: false,
|
|
598
609
|
stash: true,
|
|
599
|
-
verbose: false
|
|
610
|
+
verbose: false,
|
|
600
611
|
})
|
|
601
612
|
```
|
|
602
613
|
|
|
@@ -713,6 +724,30 @@ Example repo: [sudo-suhas/lint-staged-django-react-demo](https://github.com/sudo
|
|
|
713
724
|
|
|
714
725
|
</details>
|
|
715
726
|
|
|
727
|
+
### Can I run `lint-staged` in CI, or when there are no staged files?
|
|
728
|
+
|
|
729
|
+
<details>
|
|
730
|
+
<summary>Click to expand</summary>
|
|
731
|
+
|
|
732
|
+
Lint-staged will by default run against files staged in git, and should be run during the git pre-commit hook, for example. It's also possible to override this default behaviour and run against files in a specific diff, for example
|
|
733
|
+
all changed files between two different branches. If you want to run _lint-staged_ in the CI, maybe you can set it up to compare the branch in a _Pull Request_/_Merge Request_ to the target branch.
|
|
734
|
+
|
|
735
|
+
Try out the `git diff` command until you are satisfied with the result, for example:
|
|
736
|
+
|
|
737
|
+
```
|
|
738
|
+
git diff --diff-filter=ACMR --name-only master...my-branch
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
This will print a list of _added_, _changed_, _modified_, and _renamed_ files between `master` and `my-branch`.
|
|
742
|
+
|
|
743
|
+
You can then run lint-staged against the same files with:
|
|
744
|
+
|
|
745
|
+
```
|
|
746
|
+
npx lint-staged --diff="master...my-branch"
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
</details>
|
|
750
|
+
|
|
716
751
|
### Can I use `lint-staged` with `ng lint`
|
|
717
752
|
|
|
718
753
|
<details>
|
package/bin/lint-staged.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import fs from 'fs'
|
|
4
|
-
import path from 'path'
|
|
5
|
-
import { fileURLToPath } from 'url'
|
|
3
|
+
import fs from 'node:fs'
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
import { fileURLToPath } from 'node:url'
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import { isColorSupported } from 'colorette'
|
|
8
|
+
import { Option, program } from 'commander'
|
|
8
9
|
import debug from 'debug'
|
|
9
|
-
import supportsColor from 'supports-color'
|
|
10
10
|
|
|
11
11
|
import lintStaged from '../lib/index.js'
|
|
12
12
|
import { CONFIG_STDIN_ERROR } from '../lib/messages.js'
|
|
13
13
|
|
|
14
14
|
// Force colors for packages that depend on https://www.npmjs.com/package/supports-color
|
|
15
|
-
if (
|
|
16
|
-
process.env.FORCE_COLOR =
|
|
15
|
+
if (isColorSupported) {
|
|
16
|
+
process.env.FORCE_COLOR = '1'
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
// Do not terminate main Listr process on SIGINT
|
|
@@ -23,50 +23,87 @@ const packageJsonPath = path.join(fileURLToPath(import.meta.url), '../../package
|
|
|
23
23
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath))
|
|
24
24
|
const version = packageJson.version
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
const debugLog = debug('lint-staged:bin')
|
|
27
|
+
debugLog('Running `lint-staged@%s`', version)
|
|
28
|
+
|
|
29
|
+
const cli = program.version(version)
|
|
30
|
+
|
|
31
|
+
cli.option('--allow-empty', 'allow empty commits when tasks revert all staged changes', false)
|
|
32
|
+
|
|
33
|
+
cli.option(
|
|
34
|
+
'-p, --concurrent <number|boolean>',
|
|
35
|
+
'the number of tasks to run concurrently, or false for serial',
|
|
36
|
+
true
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
cli.option('-c, --config [path]', 'path to configuration file, or - to read from stdin')
|
|
40
|
+
|
|
41
|
+
cli.option('--cwd [path]', 'run all tasks in specific directory, instead of the current')
|
|
42
|
+
|
|
43
|
+
cli.option('-d, --debug', 'print additional debug information', false)
|
|
44
|
+
|
|
45
|
+
cli.option(
|
|
46
|
+
'--diff [string]',
|
|
47
|
+
'override the default "--staged" flag of "git diff" to get list of files. Implies "--no-stash".'
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
cli.option(
|
|
51
|
+
'--diff-filter [string]',
|
|
52
|
+
'override the default "--diff-filter=ACMR" flag of "git diff" to get list of files'
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
cli.option('--max-arg-length [number]', 'maximum length of the command-line argument string', 0)
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* We don't want to show the `--stash` flag because it's on by default, and only show the
|
|
59
|
+
* negatable flag `--no-stash` in stead. There seems to be a bug in Commander.js where
|
|
60
|
+
* configuring only the latter won't actually set the default value.
|
|
61
|
+
*/
|
|
62
|
+
cli
|
|
63
|
+
.addOption(
|
|
64
|
+
new Option('--stash', 'enable the backup stash, and revert in case of errors')
|
|
65
|
+
.default(true)
|
|
66
|
+
.hideHelp()
|
|
33
67
|
)
|
|
34
|
-
.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
.option('-q, --quiet', 'disable lint-staged’s own console output', false)
|
|
40
|
-
.option('-r, --relative', 'pass relative filepaths to tasks', false)
|
|
41
|
-
.option('-x, --shell [path]', 'skip parsing of tasks for better shell support', false)
|
|
42
|
-
.option(
|
|
43
|
-
'-v, --verbose',
|
|
44
|
-
'show task output even when tasks succeed; by default only failed output is shown',
|
|
45
|
-
false
|
|
68
|
+
.addOption(
|
|
69
|
+
new Option(
|
|
70
|
+
'--no-stash',
|
|
71
|
+
'disable the backup stash, and do not revert in case of errors'
|
|
72
|
+
).default(false)
|
|
46
73
|
)
|
|
47
|
-
.parse(process.argv)
|
|
48
74
|
|
|
49
|
-
|
|
75
|
+
cli.option('-q, --quiet', 'disable lint-staged’s own console output', false)
|
|
76
|
+
|
|
77
|
+
cli.option('-r, --relative', 'pass relative filepaths to tasks', false)
|
|
78
|
+
|
|
79
|
+
cli.option('-x, --shell [path]', 'skip parsing of tasks for better shell support', false)
|
|
80
|
+
|
|
81
|
+
cli.option(
|
|
82
|
+
'-v, --verbose',
|
|
83
|
+
'show task output even when tasks succeed; by default only failed output is shown',
|
|
84
|
+
false
|
|
85
|
+
)
|
|
50
86
|
|
|
51
|
-
|
|
87
|
+
const cliOptions = cli.parse(process.argv).opts()
|
|
88
|
+
|
|
89
|
+
if (cliOptions.debug) {
|
|
52
90
|
debug.enable('lint-staged*')
|
|
53
91
|
}
|
|
54
92
|
|
|
55
|
-
const debugLog = debug('lint-staged:bin')
|
|
56
|
-
debugLog('Running `lint-staged@%s`', version)
|
|
57
|
-
|
|
58
93
|
const options = {
|
|
59
|
-
allowEmpty: !!
|
|
60
|
-
concurrent: JSON.parse(
|
|
61
|
-
configPath:
|
|
62
|
-
cwd:
|
|
63
|
-
debug: !!
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
94
|
+
allowEmpty: !!cliOptions.allowEmpty,
|
|
95
|
+
concurrent: JSON.parse(cliOptions.concurrent),
|
|
96
|
+
configPath: cliOptions.config,
|
|
97
|
+
cwd: cliOptions.cwd,
|
|
98
|
+
debug: !!cliOptions.debug,
|
|
99
|
+
diff: cliOptions.diff,
|
|
100
|
+
diffFilter: cliOptions.diffFilter,
|
|
101
|
+
maxArgLength: cliOptions.maxArgLength || undefined,
|
|
102
|
+
quiet: !!cliOptions.quiet,
|
|
103
|
+
relative: !!cliOptions.relative,
|
|
104
|
+
shell: cliOptions.shell /* Either a boolean or a string pointing to the shell */,
|
|
105
|
+
stash: !!cliOptions.stash, // commander inverts `no-<x>` flags to `!x`
|
|
106
|
+
verbose: !!cliOptions.verbose,
|
|
70
107
|
}
|
|
71
108
|
|
|
72
109
|
debugLog('Options parsed from command-line:', options)
|
package/lib/chunkFiles.js
CHANGED
package/lib/dynamicImport.js
CHANGED
package/lib/execGit.js
CHANGED
package/lib/file.js
CHANGED
package/lib/generateTasks.js
CHANGED
package/lib/getStagedFiles.js
CHANGED
|
@@ -1,18 +1,29 @@
|
|
|
1
|
-
import path from 'path'
|
|
1
|
+
import path from 'node:path'
|
|
2
2
|
|
|
3
3
|
import normalize from 'normalize-path'
|
|
4
4
|
|
|
5
5
|
import { execGit } from './execGit.js'
|
|
6
6
|
import { parseGitZOutput } from './parseGitZOutput.js'
|
|
7
7
|
|
|
8
|
-
export const getStagedFiles = async ({ cwd = process.cwd() } = {}) => {
|
|
8
|
+
export const getStagedFiles = async ({ cwd = process.cwd(), diff, diffFilter } = {}) => {
|
|
9
9
|
try {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Docs for --diff-filter option:
|
|
12
|
+
* @see https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203
|
|
13
|
+
*/
|
|
14
|
+
const diffFilterArg = diffFilter !== undefined ? diffFilter.trim() : 'ACMR'
|
|
15
15
|
|
|
16
|
+
/** Use `--diff branch1...branch2` or `--diff="branch1 branch2", or fall back to default staged files */
|
|
17
|
+
const diffArgs = diff !== undefined ? diff.trim().split(' ') : ['--staged']
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Docs for -z option:
|
|
21
|
+
* @see https://git-scm.com/docs/git-diff#Documentation/git-diff.txt--z
|
|
22
|
+
*/
|
|
23
|
+
const lines = await execGit(
|
|
24
|
+
['diff', '--name-only', '-z', `--diff-filter=${diffFilterArg}`, ...diffArgs],
|
|
25
|
+
{ cwd }
|
|
26
|
+
)
|
|
16
27
|
if (!lines) return []
|
|
17
28
|
|
|
18
29
|
return parseGitZOutput(lines).map((file) => normalize(path.resolve(cwd, file)))
|
package/lib/gitWorkflow.js
CHANGED
|
@@ -1,23 +1,19 @@
|
|
|
1
|
-
import path from 'path'
|
|
1
|
+
import path from 'node:path'
|
|
2
2
|
|
|
3
3
|
import debug from 'debug'
|
|
4
4
|
|
|
5
|
-
import { ConfigObjectSymbol } from './searchConfigs.js'
|
|
6
|
-
|
|
7
5
|
const debugLog = debug('lint-staged:groupFilesByConfig')
|
|
8
6
|
|
|
9
|
-
export const groupFilesByConfig = async ({ configs, files }) => {
|
|
7
|
+
export const groupFilesByConfig = async ({ configs, files, singleConfigMode }) => {
|
|
10
8
|
debugLog('Grouping %d files by %d configurations', files.length, Object.keys(configs).length)
|
|
11
9
|
|
|
12
10
|
const filesSet = new Set(files)
|
|
13
11
|
const filesByConfig = {}
|
|
14
12
|
|
|
15
13
|
/** Configs are sorted deepest first by `searchConfigs` */
|
|
16
|
-
for (const filepath of
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/** When passed an explicit config object via the Node.js API, skip logic */
|
|
20
|
-
if (filepath === ConfigObjectSymbol) {
|
|
14
|
+
for (const [filepath, config] of Object.entries(configs)) {
|
|
15
|
+
/** When passed an explicit config object via the Node.js API‚ or an explicit path, skip logic */
|
|
16
|
+
if (singleConfigMode) {
|
|
21
17
|
filesByConfig[filepath] = { config, files }
|
|
22
18
|
break
|
|
23
19
|
}
|
package/lib/index.js
CHANGED
|
@@ -49,6 +49,8 @@ const getMaxArgLength = () => {
|
|
|
49
49
|
* @param {string} [options.configPath] - Path to configuration file
|
|
50
50
|
* @param {Object} [options.cwd] - Current working directory
|
|
51
51
|
* @param {boolean} [options.debug] - Enable debug mode
|
|
52
|
+
* @param {string} [options.diff] - Override the default "--staged" flag of "git diff" to get list of files
|
|
53
|
+
* @param {string} [options.diffFilter] - Override the default "--diff-filter=ACMR" flag of "git diff" to get list of files
|
|
52
54
|
* @param {number} [options.maxArgLength] - Maximum argument string length
|
|
53
55
|
* @param {boolean} [options.quiet] - Disable lint-staged’s own console output
|
|
54
56
|
* @param {boolean} [options.relative] - Pass relative filepaths to tasks
|
|
@@ -67,6 +69,8 @@ const lintStaged = async (
|
|
|
67
69
|
configPath,
|
|
68
70
|
cwd,
|
|
69
71
|
debug = false,
|
|
72
|
+
diff,
|
|
73
|
+
diffFilter,
|
|
70
74
|
maxArgLength = getMaxArgLength() / 2,
|
|
71
75
|
quiet = false,
|
|
72
76
|
relative = false,
|
|
@@ -82,29 +86,30 @@ const lintStaged = async (
|
|
|
82
86
|
debugLog('Unset GIT_LITERAL_PATHSPECS (was `%s`)', process.env.GIT_LITERAL_PATHSPECS)
|
|
83
87
|
delete process.env.GIT_LITERAL_PATHSPECS
|
|
84
88
|
|
|
89
|
+
const options = {
|
|
90
|
+
allowEmpty,
|
|
91
|
+
concurrent,
|
|
92
|
+
configObject,
|
|
93
|
+
configPath,
|
|
94
|
+
cwd,
|
|
95
|
+
debug,
|
|
96
|
+
diff,
|
|
97
|
+
diffFilter,
|
|
98
|
+
maxArgLength,
|
|
99
|
+
quiet,
|
|
100
|
+
relative,
|
|
101
|
+
shell,
|
|
102
|
+
stash,
|
|
103
|
+
verbose,
|
|
104
|
+
}
|
|
105
|
+
|
|
85
106
|
try {
|
|
86
|
-
const ctx = await runAll(
|
|
87
|
-
{
|
|
88
|
-
allowEmpty,
|
|
89
|
-
concurrent,
|
|
90
|
-
configObject,
|
|
91
|
-
configPath,
|
|
92
|
-
cwd,
|
|
93
|
-
debug,
|
|
94
|
-
maxArgLength,
|
|
95
|
-
quiet,
|
|
96
|
-
relative,
|
|
97
|
-
shell,
|
|
98
|
-
stash,
|
|
99
|
-
verbose,
|
|
100
|
-
},
|
|
101
|
-
logger
|
|
102
|
-
)
|
|
107
|
+
const ctx = await runAll(options, logger)
|
|
103
108
|
debugLog('Tasks were executed successfully!')
|
|
104
109
|
printTaskOutput(ctx, logger)
|
|
105
110
|
return true
|
|
106
111
|
} catch (runAllError) {
|
|
107
|
-
if (runAllError
|
|
112
|
+
if (runAllError?.ctx?.errors) {
|
|
108
113
|
const { ctx } = runAllError
|
|
109
114
|
|
|
110
115
|
if (ctx.errors.has(ConfigNotFoundError)) {
|
package/lib/messages.js
CHANGED
|
@@ -28,8 +28,14 @@ export const NO_STAGED_FILES = `${info} No staged files found.`
|
|
|
28
28
|
|
|
29
29
|
export const NO_TASKS = `${info} No staged files match any configured task.`
|
|
30
30
|
|
|
31
|
-
export const skippingBackup = (hasInitialCommit) => {
|
|
32
|
-
const reason =
|
|
31
|
+
export const skippingBackup = (hasInitialCommit, diff) => {
|
|
32
|
+
const reason =
|
|
33
|
+
diff !== undefined
|
|
34
|
+
? '`--diff` was used'
|
|
35
|
+
: hasInitialCommit
|
|
36
|
+
? '`--no-stash` was used'
|
|
37
|
+
: 'there’s no initial commit yet'
|
|
38
|
+
|
|
33
39
|
return yellow(`${warning} Skipping backup because ${reason}.\n`)
|
|
34
40
|
}
|
|
35
41
|
|
package/lib/printTaskOutput.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export const printTaskOutput = (ctx = {}, logger) => {
|
|
7
7
|
if (!Array.isArray(ctx.output)) return
|
|
8
|
-
const log = ctx.errors
|
|
8
|
+
const log = ctx.errors?.size > 0 ? logger.error : logger.log
|
|
9
9
|
for (const line of ctx.output) {
|
|
10
10
|
log(line)
|
|
11
11
|
}
|
package/lib/resolveConfig.js
CHANGED
package/lib/resolveGitRepo.js
CHANGED
package/lib/resolveTaskFn.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { redBright, dim } from 'colorette'
|
|
2
|
-
import execa from 'execa'
|
|
2
|
+
import { execa, execaCommand } from 'execa'
|
|
3
3
|
import debug from 'debug'
|
|
4
4
|
import { parseArgsStringToArgv } from 'string-argv'
|
|
5
5
|
import pidTree from 'pidtree'
|
|
@@ -139,7 +139,7 @@ export const resolveTaskFn = ({
|
|
|
139
139
|
|
|
140
140
|
return async (ctx = getInitialState()) => {
|
|
141
141
|
const execaChildProcess = shell
|
|
142
|
-
?
|
|
142
|
+
? execaCommand(isFn ? command : `${command} ${files.join(' ')}`, execaOptions)
|
|
143
143
|
: execa(cmd, isFn ? args : args.concat(files), execaOptions)
|
|
144
144
|
|
|
145
145
|
const quitInterruptCheck = interruptExecutionOnError(ctx, execaChildProcess)
|
package/lib/runAll.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @typedef {import('./index').Logger} Logger */
|
|
2
2
|
|
|
3
|
-
import path from 'path'
|
|
3
|
+
import path from 'node:path'
|
|
4
4
|
|
|
5
5
|
import { dim } from 'colorette'
|
|
6
6
|
import debug from 'debug'
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
restoreUnstagedChangesSkipped,
|
|
37
37
|
} from './state.js'
|
|
38
38
|
import { GitRepoError, GetStagedFilesError, GitError, ConfigNotFoundError } from './symbols.js'
|
|
39
|
-
import {
|
|
39
|
+
import { searchConfigs } from './searchConfigs.js'
|
|
40
40
|
|
|
41
41
|
const debugLog = debug('lint-staged:runAll')
|
|
42
42
|
|
|
@@ -52,6 +52,8 @@ const createError = (ctx) => Object.assign(new Error('lint-staged failed'), { ct
|
|
|
52
52
|
* @param {string} [options.configPath] - Explicit path to a config file
|
|
53
53
|
* @param {string} [options.cwd] - Current working directory
|
|
54
54
|
* @param {boolean} [options.debug] - Enable debug mode
|
|
55
|
+
* @param {string} [options.diff] - Override the default "--staged" flag of "git diff" to get list of files
|
|
56
|
+
* @param {string} [options.diffFilter] - Override the default "--diff-filter=ACMR" flag of "git diff" to get list of files
|
|
55
57
|
* @param {number} [options.maxArgLength] - Maximum argument string length
|
|
56
58
|
* @param {boolean} [options.quiet] - Disable lint-staged’s own console output
|
|
57
59
|
* @param {boolean} [options.relative] - Pass relative filepaths to tasks
|
|
@@ -69,6 +71,8 @@ export const runAll = async (
|
|
|
69
71
|
configPath,
|
|
70
72
|
cwd,
|
|
71
73
|
debug = false,
|
|
74
|
+
diff,
|
|
75
|
+
diffFilter,
|
|
72
76
|
maxArgLength,
|
|
73
77
|
quiet = false,
|
|
74
78
|
relative = false,
|
|
@@ -100,13 +104,14 @@ export const runAll = async (
|
|
|
100
104
|
.then(() => true)
|
|
101
105
|
.catch(() => false)
|
|
102
106
|
|
|
103
|
-
// Lint-staged should create a backup stash only when there's an initial commit
|
|
104
|
-
|
|
107
|
+
// Lint-staged should create a backup stash only when there's an initial commit,
|
|
108
|
+
// and when using the default list of staged files
|
|
109
|
+
ctx.shouldBackup = hasInitialCommit && stash && diff === undefined
|
|
105
110
|
if (!ctx.shouldBackup) {
|
|
106
|
-
logger.warn(skippingBackup(hasInitialCommit))
|
|
111
|
+
logger.warn(skippingBackup(hasInitialCommit, diff))
|
|
107
112
|
}
|
|
108
113
|
|
|
109
|
-
const files = await getStagedFiles({ cwd: gitDir })
|
|
114
|
+
const files = await getStagedFiles({ cwd: gitDir, diff, diffFilter })
|
|
110
115
|
if (!files) {
|
|
111
116
|
if (!quiet) ctx.output.push(FAILED_GET_STAGED_FILES)
|
|
112
117
|
ctx.errors.add(GetStagedFilesError)
|
|
@@ -121,7 +126,7 @@ export const runAll = async (
|
|
|
121
126
|
}
|
|
122
127
|
|
|
123
128
|
const foundConfigs = await searchConfigs({ configObject, configPath, cwd, gitDir }, logger)
|
|
124
|
-
const numberOfConfigs =
|
|
129
|
+
const numberOfConfigs = Object.keys(foundConfigs).length
|
|
125
130
|
|
|
126
131
|
// Throw if no configurations were found
|
|
127
132
|
if (numberOfConfigs === 0) {
|
|
@@ -129,7 +134,11 @@ export const runAll = async (
|
|
|
129
134
|
throw createError(ctx, ConfigNotFoundError)
|
|
130
135
|
}
|
|
131
136
|
|
|
132
|
-
const filesByConfig = await groupFilesByConfig({
|
|
137
|
+
const filesByConfig = await groupFilesByConfig({
|
|
138
|
+
configs: foundConfigs,
|
|
139
|
+
files,
|
|
140
|
+
singleConfigMode: configObject || configPath !== undefined,
|
|
141
|
+
})
|
|
133
142
|
|
|
134
143
|
const hasMultipleConfigs = numberOfConfigs > 1
|
|
135
144
|
|
|
@@ -149,13 +158,8 @@ export const runAll = async (
|
|
|
149
158
|
// Set of all staged files that matched a task glob. Values in a set are unique.
|
|
150
159
|
const matchedFiles = new Set()
|
|
151
160
|
|
|
152
|
-
for (const configPath of
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
const configName =
|
|
156
|
-
configPath === ConfigObjectSymbol
|
|
157
|
-
? 'Config object'
|
|
158
|
-
: normalize(path.relative(cwd, configPath))
|
|
161
|
+
for (const [configPath, { config, files }] of Object.entries(filesByConfig)) {
|
|
162
|
+
const configName = configPath ? normalize(path.relative(cwd, configPath)) : 'Config object'
|
|
159
163
|
|
|
160
164
|
const stagedFileChunks = chunkFiles({ baseDir: gitDir, files, maxArgLength, relative })
|
|
161
165
|
|
package/lib/searchConfigs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @typedef {import('./index').Logger} Logger */
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import path from 'node:path'
|
|
4
4
|
|
|
5
5
|
import debug from 'debug'
|
|
6
6
|
import normalize from 'normalize-path'
|
|
@@ -15,7 +15,7 @@ const debugLog = debug('lint-staged:searchConfigs')
|
|
|
15
15
|
const EXEC_GIT = ['ls-files', '-z', '--full-name']
|
|
16
16
|
|
|
17
17
|
const filterPossibleConfigFiles = (files) =>
|
|
18
|
-
files.filter((file) => searchPlaces.includes(basename(file)))
|
|
18
|
+
files.filter((file) => searchPlaces.includes(path.basename(file)))
|
|
19
19
|
|
|
20
20
|
const numberOfLevels = (file) => file.split('/').length
|
|
21
21
|
|
|
@@ -23,8 +23,6 @@ const sortDeepestParth = (a, b) => (numberOfLevels(a) > numberOfLevels(b) ? -1 :
|
|
|
23
23
|
|
|
24
24
|
const isInsideDirectory = (dir) => (file) => file.startsWith(normalize(dir))
|
|
25
25
|
|
|
26
|
-
export const ConfigObjectSymbol = Symbol()
|
|
27
|
-
|
|
28
26
|
/**
|
|
29
27
|
* Search all config files from the git repository, preferring those inside `cwd`.
|
|
30
28
|
*
|
|
@@ -46,7 +44,7 @@ export const searchConfigs = async (
|
|
|
46
44
|
if (configObject) {
|
|
47
45
|
debugLog('Using single direct configuration object...')
|
|
48
46
|
|
|
49
|
-
return {
|
|
47
|
+
return { '': validateConfig(configObject, 'config object', logger) }
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
// Use only explicit config path instead of discovering multiple
|
|
@@ -70,7 +68,7 @@ export const searchConfigs = async (
|
|
|
70
68
|
|
|
71
69
|
/** Sort possible config files so that deepest is first */
|
|
72
70
|
const possibleConfigFiles = [...cachedFiles, ...otherFiles]
|
|
73
|
-
.map((file) => normalize(join(gitDir, file)))
|
|
71
|
+
.map((file) => normalize(path.join(gitDir, file)))
|
|
74
72
|
.filter(isInsideDirectory(cwd))
|
|
75
73
|
.sort(sortDeepestParth)
|
|
76
74
|
|
package/lib/validateOptions.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lint-staged",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "13.0.0",
|
|
4
4
|
"description": "Lint files staged by git",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "https://github.com/okonet/lint-staged",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"url": "https://opencollective.com/lint-staged"
|
|
15
15
|
},
|
|
16
16
|
"engines": {
|
|
17
|
-
"node": "^
|
|
17
|
+
"node": "^14.13.1 || >=16.0.0"
|
|
18
18
|
},
|
|
19
19
|
"type": "module",
|
|
20
20
|
"bin": "./bin/lint-staged.js",
|
|
@@ -34,35 +34,35 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"cli-truncate": "^3.1.0",
|
|
36
36
|
"colorette": "^2.0.16",
|
|
37
|
-
"commander": "^
|
|
38
|
-
"debug": "^4.3.
|
|
39
|
-
"execa": "^
|
|
40
|
-
"lilconfig": "2.0.
|
|
41
|
-
"listr2": "^4.0.
|
|
42
|
-
"micromatch": "^4.0.
|
|
37
|
+
"commander": "^9.3.0",
|
|
38
|
+
"debug": "^4.3.4",
|
|
39
|
+
"execa": "^6.1.0",
|
|
40
|
+
"lilconfig": "2.0.5",
|
|
41
|
+
"listr2": "^4.0.5",
|
|
42
|
+
"micromatch": "^4.0.5",
|
|
43
43
|
"normalize-path": "^3.0.0",
|
|
44
|
-
"object-inspect": "^1.12.
|
|
44
|
+
"object-inspect": "^1.12.2",
|
|
45
45
|
"pidtree": "^0.5.0",
|
|
46
46
|
"string-argv": "^0.3.1",
|
|
47
|
-
"
|
|
48
|
-
"yaml": "^1.10.2"
|
|
47
|
+
"yaml": "^2.1.1"
|
|
49
48
|
},
|
|
50
49
|
"devDependencies": {
|
|
51
|
-
"@babel/core": "^7.
|
|
52
|
-
"@babel/eslint-parser": "^7.
|
|
53
|
-
"@babel/preset-env": "^7.
|
|
54
|
-
"babel-jest": "^
|
|
50
|
+
"@babel/core": "^7.18.2",
|
|
51
|
+
"@babel/eslint-parser": "^7.18.2",
|
|
52
|
+
"@babel/preset-env": "^7.18.2",
|
|
53
|
+
"babel-jest": "^28.1.0",
|
|
54
|
+
"babel-plugin-transform-imports": "2.0.0",
|
|
55
55
|
"consolemock": "^1.1.0",
|
|
56
|
-
"eslint": "^8.
|
|
57
|
-
"eslint-config-prettier": "^8.
|
|
58
|
-
"eslint-plugin-import": "^2.
|
|
56
|
+
"eslint": "^8.16.0",
|
|
57
|
+
"eslint-config-prettier": "^8.5.0",
|
|
58
|
+
"eslint-plugin-import": "^2.26.0",
|
|
59
59
|
"eslint-plugin-node": "^11.1.0",
|
|
60
60
|
"eslint-plugin-prettier": "^4.0.0",
|
|
61
|
-
"fs-extra": "^10.
|
|
62
|
-
"husky": "^
|
|
63
|
-
"jest": "^
|
|
61
|
+
"fs-extra": "^10.1.0",
|
|
62
|
+
"husky": "^8.0.1",
|
|
63
|
+
"jest": "^28.1.0",
|
|
64
64
|
"jest-snapshot-serializer-ansi": "^1.0.0",
|
|
65
|
-
"prettier": "^2.
|
|
65
|
+
"prettier": "^2.6.2"
|
|
66
66
|
},
|
|
67
67
|
"keywords": [
|
|
68
68
|
"lint",
|