1 | 'use strict'
|
2 |
|
3 | const dedent = require('dedent')
|
4 | const { cosmiconfig } = require('cosmiconfig')
|
5 | const debugLog = require('debug')('lint-staged')
|
6 | const stringifyObject = require('stringify-object')
|
7 |
|
8 | const { PREVENTED_EMPTY_COMMIT, GIT_ERROR, RESTORE_STASH_EXAMPLE } = require('./messages')
|
9 | const printTaskOutput = require('./printTaskOutput')
|
10 | const runAll = require('./runAll')
|
11 | const { ApplyEmptyCommitError, GetBackupStashError, GitError } = require('./symbols')
|
12 | const validateConfig = require('./validateConfig')
|
13 |
|
14 | const errConfigNotFound = new Error('Config could not be found')
|
15 |
|
16 | function resolveConfig(configPath) {
|
17 | try {
|
18 | return require.resolve(configPath)
|
19 | } catch {
|
20 | return configPath
|
21 | }
|
22 | }
|
23 |
|
24 | function loadConfig(configPath) {
|
25 | const explorer = cosmiconfig('lint-staged', {
|
26 | searchPlaces: [
|
27 | 'package.json',
|
28 | '.lintstagedrc',
|
29 | '.lintstagedrc.json',
|
30 | '.lintstagedrc.yaml',
|
31 | '.lintstagedrc.yml',
|
32 | '.lintstagedrc.js',
|
33 | 'lint-staged.config.js',
|
34 | ],
|
35 | })
|
36 |
|
37 | return configPath ? explorer.load(resolveConfig(configPath)) : explorer.search()
|
38 | }
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 | module.exports = async function lintStaged(
|
64 | {
|
65 | allowEmpty = false,
|
66 | concurrent = true,
|
67 | config: configObject,
|
68 | configPath,
|
69 | cwd = process.cwd(),
|
70 | debug = false,
|
71 | maxArgLength,
|
72 | quiet = false,
|
73 | relative = false,
|
74 | shell = false,
|
75 | stash = true,
|
76 | verbose = false,
|
77 | } = {},
|
78 | logger = console
|
79 | ) {
|
80 | try {
|
81 | debugLog('Loading config using `cosmiconfig`')
|
82 |
|
83 | const resolved = configObject
|
84 | ? { config: configObject, filepath: '(input)' }
|
85 | : await loadConfig(configPath)
|
86 | if (resolved == null) throw errConfigNotFound
|
87 |
|
88 | debugLog('Successfully loaded config from `%s`:\n%O', resolved.filepath, resolved.config)
|
89 |
|
90 |
|
91 | const config = validateConfig(resolved.config)
|
92 | if (debug) {
|
93 |
|
94 | logger.log('Running lint-staged with the following config:')
|
95 | logger.log(stringifyObject(config, { indent: ' ' }))
|
96 | } else {
|
97 |
|
98 |
|
99 | debugLog('lint-staged config:\n%O', config)
|
100 | }
|
101 |
|
102 |
|
103 | debugLog('Unset GIT_LITERAL_PATHSPECS (was `%s`)', process.env.GIT_LITERAL_PATHSPECS)
|
104 | delete process.env.GIT_LITERAL_PATHSPECS
|
105 |
|
106 | try {
|
107 | const ctx = await runAll(
|
108 | {
|
109 | allowEmpty,
|
110 | concurrent,
|
111 | config,
|
112 | cwd,
|
113 | debug,
|
114 | maxArgLength,
|
115 | quiet,
|
116 | relative,
|
117 | shell,
|
118 | stash,
|
119 | verbose,
|
120 | },
|
121 | logger
|
122 | )
|
123 | debugLog('Tasks were executed successfully!')
|
124 | printTaskOutput(ctx, logger)
|
125 | return true
|
126 | } catch (runAllError) {
|
127 | const { ctx } = runAllError
|
128 | if (ctx.errors.has(ApplyEmptyCommitError)) {
|
129 | logger.warn(PREVENTED_EMPTY_COMMIT)
|
130 | } else if (ctx.errors.has(GitError) && !ctx.errors.has(GetBackupStashError)) {
|
131 | logger.error(GIT_ERROR)
|
132 | if (ctx.shouldBackup) {
|
133 |
|
134 | logger.error(RESTORE_STASH_EXAMPLE)
|
135 | }
|
136 | }
|
137 |
|
138 | printTaskOutput(ctx, logger)
|
139 | return false
|
140 | }
|
141 | } catch (lintStagedError) {
|
142 | if (lintStagedError === errConfigNotFound) {
|
143 | logger.error(`${lintStagedError.message}.`)
|
144 | } else {
|
145 |
|
146 | logger.error(dedent`
|
147 | Could not parse lint-staged config.
|
148 |
|
149 | ${lintStagedError}
|
150 | `)
|
151 | }
|
152 | logger.error()
|
153 |
|
154 | logger.error(dedent`
|
155 | Please make sure you have created it correctly.
|
156 | See https://github.com/okonet/lint-staged#configuration.
|
157 | `)
|
158 |
|
159 | throw lintStagedError
|
160 | }
|
161 | }
|