1 | import debug from 'debug'
|
2 |
|
3 | import { PREVENTED_EMPTY_COMMIT, GIT_ERROR, RESTORE_STASH_EXAMPLE } from './messages.js'
|
4 | import { printTaskOutput } from './printTaskOutput.js'
|
5 | import { runAll } from './runAll.js'
|
6 | import { ApplyEmptyCommitError, GetBackupStashError, GitError } from './symbols.js'
|
7 | import { validateOptions } from './validateOptions.js'
|
8 |
|
9 | const debugLog = debug('lint-staged')
|
10 |
|
11 | /**
|
12 | * @typedef {(...any) => void} LogFunction
|
13 | * @typedef {{ error: LogFunction, log: LogFunction, warn: LogFunction }} Logger
|
14 | *
|
15 | * Root lint-staged function that is called from `bin/lint-staged`.
|
16 | *
|
17 | * @param {object} options
|
18 | * @param {Object} [options.allowEmpty] - Allow empty commits when tasks revert all staged changes
|
19 | * @param {boolean | number} [options.concurrent] - The number of tasks to run concurrently, or false to run tasks serially
|
20 | * @param {object} [options.config] - Object with configuration for programmatic API
|
21 | * @param {string} [options.configPath] - Path to configuration file
|
22 | * @param {Object} [options.cwd] - Current working directory
|
23 | * @param {boolean} [options.debug] - Enable debug mode
|
24 | * @param {number} [options.maxArgLength] - Maximum argument string length
|
25 | * @param {boolean} [options.quiet] - Disable lint-staged’s own console output
|
26 | * @param {boolean} [options.relative] - Pass relative filepaths to tasks
|
27 | * @param {boolean|string} [options.shell] - Skip parsing of tasks for better shell support
|
28 | * @param {boolean} [options.stash] - Enable the backup stash, and revert in case of errors
|
29 | * @param {boolean} [options.verbose] - Show task output even when tasks succeed; by default only failed output is shown
|
30 | * @param {Logger} [logger]
|
31 | *
|
32 | * @returns {Promise<boolean>} Promise of whether the linting passed or failed
|
33 | */
|
34 | const lintStaged = async (
|
35 | {
|
36 | allowEmpty = false,
|
37 | concurrent = true,
|
38 | config: configObject,
|
39 | configPath,
|
40 | cwd,
|
41 | debug = false,
|
42 | maxArgLength,
|
43 | quiet = false,
|
44 | relative = false,
|
45 | shell = false,
|
46 | stash = true,
|
47 | verbose = false,
|
48 | } = {},
|
49 | logger = console
|
50 | ) => {
|
51 | await validateOptions({ cwd, shell }, logger)
|
52 |
|
53 | // Unset GIT_LITERAL_PATHSPECS to not mess with path interpretation
|
54 | debugLog('Unset GIT_LITERAL_PATHSPECS (was `%s`)', process.env.GIT_LITERAL_PATHSPECS)
|
55 | delete process.env.GIT_LITERAL_PATHSPECS
|
56 |
|
57 | try {
|
58 | const ctx = await runAll(
|
59 | {
|
60 | allowEmpty,
|
61 | concurrent,
|
62 | configObject,
|
63 | configPath,
|
64 | cwd,
|
65 | debug,
|
66 | maxArgLength,
|
67 | quiet,
|
68 | relative,
|
69 | shell,
|
70 | stash,
|
71 | verbose,
|
72 | },
|
73 | logger
|
74 | )
|
75 | debugLog('Tasks were executed successfully!')
|
76 | printTaskOutput(ctx, logger)
|
77 | return true
|
78 | } catch (runAllError) {
|
79 | if (runAllError && runAllError.ctx && runAllError.ctx.errors) {
|
80 | const { ctx } = runAllError
|
81 | if (ctx.errors.has(ApplyEmptyCommitError)) {
|
82 | logger.warn(PREVENTED_EMPTY_COMMIT)
|
83 | } else if (ctx.errors.has(GitError) && !ctx.errors.has(GetBackupStashError)) {
|
84 | logger.error(GIT_ERROR)
|
85 | if (ctx.shouldBackup) {
|
86 | // No sense to show this if the backup stash itself is missing.
|
87 | logger.error(RESTORE_STASH_EXAMPLE)
|
88 | }
|
89 | }
|
90 |
|
91 | printTaskOutput(ctx, logger)
|
92 | return false
|
93 | }
|
94 |
|
95 | // Probably a compilation error in the config js file. Pass it up to the outer error handler for logging.
|
96 | throw runAllError
|
97 | }
|
98 | }
|
99 |
|
100 | export default lintStaged
|