gulp-eslint-new 1.1.2 → 1.2.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 +105 -100
- package/index.js +59 -62
- package/package.json +11 -9
- package/util.js +196 -211
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ npm i -D gulp-eslint-new
|
|
|
12
12
|
|
|
13
13
|
## Migrating
|
|
14
14
|
|
|
15
|
-
If you are migrating from gulp-eslint, you probably won't need to change any settings in your
|
|
15
|
+
If you are migrating from [gulp-eslint][gulp-eslint], you probably won't need to change any settings in your gulp task.
|
|
16
16
|
gulp-eslint-new can handle most of the options used with gulp-eslint, although some of them are now deprecated in favor of a new name or format.
|
|
17
17
|
|
|
18
18
|
Anyway, since gulp-eslint-new uses ESLint 8 while gulp-eslint sticks to ESLint 6, you may need to make some changes to your project to address incompatibilities between the versions of ESLint.
|
|
@@ -24,27 +24,27 @@ You can find more information at the links below.
|
|
|
24
24
|
|
|
25
25
|
```javascript
|
|
26
26
|
const { src } = require('gulp');
|
|
27
|
-
const
|
|
27
|
+
const gulpESLintNew = require('gulp-eslint-new');
|
|
28
28
|
|
|
29
29
|
// Define the default gulp task.
|
|
30
30
|
exports.default =
|
|
31
31
|
() => src(['scripts/*.js'])
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
.pipe(
|
|
35
|
-
//
|
|
36
|
-
// Alternatively use
|
|
37
|
-
.pipe(
|
|
38
|
-
// To have the process exit with an error code (1) on lint error,
|
|
39
|
-
//
|
|
40
|
-
.pipe(
|
|
32
|
+
// gulpESLintNew() attaches the lint output to the "eslint" property of the
|
|
33
|
+
// file object so it can be used by other modules.
|
|
34
|
+
.pipe(gulpESLintNew())
|
|
35
|
+
// gulpESLintNew.format() outputs the lint results to the console.
|
|
36
|
+
// Alternatively use gulpESLintNew.formatEach() (see docs).
|
|
37
|
+
.pipe(gulpESLintNew.format())
|
|
38
|
+
// To have the process exit with an error code (1) on lint error, return the
|
|
39
|
+
// stream and pipe to failAfterError last.
|
|
40
|
+
.pipe(gulpESLintNew.failAfterError());
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
Or use the plugin API to do things like:
|
|
44
44
|
|
|
45
45
|
```javascript
|
|
46
46
|
gulp.src(['**/*.js', '!node_modules/**'])
|
|
47
|
-
.pipe(
|
|
47
|
+
.pipe(gulpESLintNew({
|
|
48
48
|
overrideConfig: {
|
|
49
49
|
rules: {
|
|
50
50
|
'my-custom-rule': 1,
|
|
@@ -60,22 +60,22 @@ gulp.src(['**/*.js', '!node_modules/**'])
|
|
|
60
60
|
},
|
|
61
61
|
warnIgnored: true
|
|
62
62
|
}))
|
|
63
|
-
.pipe(
|
|
63
|
+
.pipe(gulpESLintNew.formatEach('compact', process.stderr));
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
For additional examples, look through the [example directory](https://github.com/fasttime/gulp-eslint-new/tree/main/example).
|
|
67
67
|
|
|
68
68
|
## API
|
|
69
69
|
|
|
70
|
-
### `
|
|
70
|
+
### `gulpESLintNew()`
|
|
71
71
|
|
|
72
72
|
*No explicit configuration.* A `.eslintrc` file may be resolved relative to each linted file.
|
|
73
73
|
|
|
74
|
-
### `
|
|
74
|
+
### `gulpESLintNew(options)`
|
|
75
75
|
|
|
76
76
|
Param type: `Object`
|
|
77
77
|
|
|
78
|
-
Supported options include all [linting options]
|
|
78
|
+
Supported options include all [linting options][linting options] and [autofix options](https://eslint.org/docs/developer-guide/nodejs-api#autofix) of the `ESLint` constructor.
|
|
79
79
|
Please, refer to the ESLint documentation for information about the usage of those options.
|
|
80
80
|
Check also the notes about the [Autofix Function](#autofix-function).
|
|
81
81
|
Additionally, gulp-eslint-new supports the options listed below.
|
|
@@ -96,7 +96,7 @@ The location of the files to be linted is not related to the working directory.
|
|
|
96
96
|
|
|
97
97
|
Type: `boolean`
|
|
98
98
|
|
|
99
|
-
When `false`,
|
|
99
|
+
When `false`, ESLint will not respect `.eslintignore` files or ignore patterns in your configurations.
|
|
100
100
|
|
|
101
101
|
##### `options.ignorePath`
|
|
102
102
|
|
|
@@ -110,7 +110,7 @@ Type: `boolean`
|
|
|
110
110
|
|
|
111
111
|
When `true`, this option will filter warning messages from ESLint results. This mimics the ESLint CLI [`--quiet` option](https://eslint.org/docs/user-guide/command-line-interface#--quiet).
|
|
112
112
|
|
|
113
|
-
Type: `(message, index, list) =>
|
|
113
|
+
Type: `(message: string, index: number, list: Object[]) => unknown`
|
|
114
114
|
|
|
115
115
|
When a function is provided, it will be used to filter ESLint result messages, removing any messages that do not return a `true` (or truthy) value.
|
|
116
116
|
|
|
@@ -118,123 +118,107 @@ When a function is provided, it will be used to filter ESLint result messages, r
|
|
|
118
118
|
|
|
119
119
|
Type: `boolean`
|
|
120
120
|
|
|
121
|
-
When `true`, add a result warning when ESLint ignores a file.
|
|
121
|
+
When `true`, add a result warning when ESLint ignores a file.
|
|
122
|
+
This can be used to find files that are needlessly being loaded by `gulp.src`.
|
|
123
|
+
For example, since ESLint automatically ignores file paths inside a `node_modules` directory but `gulp.src` does not, a gulp task may take seconds longer just reading files from `node_modules`.
|
|
122
124
|
|
|
123
125
|
#### Legacy Options
|
|
124
126
|
|
|
125
|
-
The following options are provided for backward compatibility with [gulp-eslint]
|
|
127
|
+
The following options are provided for backward compatibility with [gulp-eslint][gulp-eslint].
|
|
126
128
|
Their usage is discouraged because preferable alternatives exist, that are more in line with the present ESLint conventions.
|
|
127
129
|
|
|
128
130
|
##### `options.configFile`
|
|
129
131
|
|
|
130
132
|
Type: `string`
|
|
131
133
|
|
|
132
|
-
_A legacy synonym for `options.overrideConfigFile
|
|
134
|
+
_A legacy synonym for `options.overrideConfigFile` (see [linting options][linting options])._
|
|
133
135
|
|
|
134
136
|
##### `options.envs`
|
|
135
137
|
|
|
136
138
|
Type: `string[]`
|
|
137
139
|
|
|
138
|
-
Specify a list of
|
|
140
|
+
Specify a list of environments to be applied.
|
|
139
141
|
|
|
140
|
-
_Prefer using `options.overrideConfig.env` instead. Note the different option name and format._
|
|
142
|
+
_Prefer using [`options.overrideConfig.env`](https://eslint.org/docs/user-guide/configuring/language-options#specifying-environments) instead. Note the different option name and format._
|
|
141
143
|
|
|
142
144
|
##### `options.globals`
|
|
143
145
|
|
|
144
146
|
Type: `string[]`
|
|
145
147
|
|
|
146
|
-
Specify
|
|
148
|
+
Specify a list of global variables to declare.
|
|
149
|
+
Variables declared with this option are considered readonly.
|
|
147
150
|
|
|
148
|
-
|
|
149
|
-
{
|
|
150
|
-
"globals": [
|
|
151
|
-
"jQuery",
|
|
152
|
-
"$"
|
|
153
|
-
]
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
_Prefer using `options.overrideConfig.globals` instead. Note the different format._
|
|
151
|
+
_Prefer using [`options.overrideConfig.globals`](https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals) instead. Note the different format._
|
|
158
152
|
|
|
159
153
|
##### `options.parser`
|
|
160
154
|
|
|
161
155
|
Type: `string`
|
|
162
156
|
|
|
163
|
-
_Prefer using `options.overrideConfig.parser` instead._
|
|
157
|
+
_Prefer using [`options.overrideConfig.parser`](https://eslint.org/docs/user-guide/configuring/plugins#specifying-parser) instead._
|
|
164
158
|
|
|
165
159
|
##### `options.parserOptions`
|
|
166
160
|
|
|
167
161
|
Type: `Object`
|
|
168
162
|
|
|
169
|
-
_Prefer using `options.overrideConfig.parserOptions` instead._
|
|
163
|
+
_Prefer using [`options.overrideConfig.parserOptions`](https://eslint.org/docs/user-guide/configuring/language-options#specifying-parser-options) instead._
|
|
170
164
|
|
|
171
165
|
##### `options.rules`
|
|
172
166
|
|
|
173
167
|
Type: `Object`
|
|
174
168
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
```javascript
|
|
178
|
-
{
|
|
179
|
-
"rules": {
|
|
180
|
-
"camelcase": 1,
|
|
181
|
-
"comma-dangle": 2,
|
|
182
|
-
"quotes": 0
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
_Prefer using `options.overrideConfig.rules` instead._
|
|
169
|
+
_Prefer using [`options.overrideConfig.rules`](https://eslint.org/docs/user-guide/configuring/rules) instead._
|
|
188
170
|
|
|
189
171
|
##### `options.warnFileIgnored`
|
|
190
172
|
|
|
191
173
|
Type: `boolean`
|
|
192
174
|
|
|
193
|
-
_A legacy synonym for `options.warnIgnored
|
|
175
|
+
_A legacy synonym for [`options.warnIgnored`](#optionswarnignored)._
|
|
194
176
|
|
|
195
177
|
#### Autofix Function
|
|
196
178
|
|
|
197
179
|
When the `fix` option is specified, fixes are applied to the gulp stream.
|
|
198
|
-
The fixed content can be saved to file using `
|
|
180
|
+
The fixed content can be saved to file using [`gulpESLintNew.fix()`](#gulpeslintnewfix) (See [example/fix.js](https://github.com/fasttime/gulp-eslint-new/blob/main/example/fix.js)).
|
|
199
181
|
Rules that are fixable can be found in ESLint's [rules list](https://eslint.org/docs/rules/).
|
|
200
182
|
When fixes are applied, a "fixed" property is set to `true` on the fixed file's ESLint result.
|
|
201
183
|
|
|
202
|
-
### `
|
|
184
|
+
### `gulpESLintNew(overrideConfigFile)`
|
|
203
185
|
|
|
204
186
|
Param type: `string`
|
|
205
187
|
|
|
206
188
|
Shorthand for defining `options.overrideConfigFile`.
|
|
207
189
|
|
|
208
|
-
### `
|
|
190
|
+
### `gulpESLintNew.result(action)`
|
|
209
191
|
|
|
210
|
-
Param type: `(result) => void`
|
|
192
|
+
Param type: `(result: Object) => void`
|
|
211
193
|
|
|
212
194
|
Call a function for each ESLint file result. No returned value is expected. If an error is thrown, it will be wrapped in a gulp `PluginError` and emitted from the stream.
|
|
213
195
|
|
|
214
196
|
```javascript
|
|
215
|
-
gulp.src(['**/*.js','!node_modules/**'])
|
|
216
|
-
.pipe(
|
|
217
|
-
.pipe(
|
|
197
|
+
gulp.src(['**/*.js', '!node_modules/**'])
|
|
198
|
+
.pipe(gulpESLintNew())
|
|
199
|
+
.pipe(gulpESLintNew.result(result => {
|
|
218
200
|
// Called for each ESLint result.
|
|
219
201
|
console.log(`ESLint result: ${result.filePath}`);
|
|
220
202
|
console.log(`# Messages: ${result.messages.length}`);
|
|
221
|
-
console.log(`# Warnings: ${result.warningCount} (${
|
|
222
|
-
|
|
203
|
+
console.log(`# Warnings: ${result.warningCount} (${
|
|
204
|
+
result.fixableWarningCount} fixable)`);
|
|
205
|
+
console.log(`# Errors: ${result.errorCount} (${
|
|
206
|
+
result.fixableErrorCount} fixable, ${
|
|
223
207
|
result.fatalErrorCount} fatal)`);
|
|
224
208
|
}));
|
|
225
209
|
```
|
|
226
210
|
|
|
227
|
-
Type: `(result, callback) => void`
|
|
211
|
+
Type: `(result: Object, callback: Function) => void`
|
|
228
212
|
|
|
229
213
|
Call an asynchronous, Node-style callback-based function for each ESLint file result. The callback must be called for the stream to finish. If an error is passed to the callback, it will be wrapped in a gulp `PluginError` and emitted from the stream.
|
|
230
214
|
|
|
231
|
-
Type: `result => Promise<void>`
|
|
215
|
+
Type: `(result: Object) => Promise<void>`
|
|
232
216
|
|
|
233
217
|
Call an asynchronous, promise-based function for each ESLint file result. If the promise is rejected, the rejection reason will be wrapped in a gulp `PluginError` and emitted from the stream.
|
|
234
218
|
|
|
235
|
-
### `
|
|
219
|
+
### `gulpESLintNew.results(action)`
|
|
236
220
|
|
|
237
|
-
Param type: `(results) => void`
|
|
221
|
+
Param type: `(results: Object[]) => void`
|
|
238
222
|
|
|
239
223
|
Call a function once for all ESLint file results before a stream finishes. No returned value is expected. If an error is thrown, it will be wrapped in a gulp `PluginError` and emitted from the stream.
|
|
240
224
|
|
|
@@ -264,94 +248,115 @@ The results list has additional properties that indicate the number of messages
|
|
|
264
248
|
</table>
|
|
265
249
|
|
|
266
250
|
```javascript
|
|
267
|
-
gulp.src(['**/*.js','!node_modules/**'])
|
|
268
|
-
.pipe(
|
|
269
|
-
.pipe(
|
|
251
|
+
gulp.src(['**/*.js', '!node_modules/**'])
|
|
252
|
+
.pipe(gulpESLintNew())
|
|
253
|
+
.pipe(gulpESLintNew.results(results => {
|
|
270
254
|
// Called once for all ESLint results.
|
|
271
255
|
console.log(`Total Results: ${results.length}`);
|
|
272
256
|
console.log(`Total Warnings: ${results.warningCount} (${
|
|
273
257
|
results.fixableWarningCount} fixable)`);
|
|
274
|
-
console.log(`Total Errors: ${results.errorCount} (${
|
|
258
|
+
console.log(`Total Errors: ${results.errorCount} (${
|
|
259
|
+
results.fixableErrorCount} fixable, ${
|
|
275
260
|
results.fatalErrorCount} fatal)`);
|
|
276
261
|
}));
|
|
277
262
|
```
|
|
278
263
|
|
|
279
|
-
Param type: `(results, callback) => void`
|
|
264
|
+
Param type: `(results: Object[], callback: Function) => void`
|
|
280
265
|
|
|
281
266
|
Call an asynchronous, Node-style callback-based function once for all ESLint file results before a stream finishes. The callback must be called for the stream to finish. If an error is passed to the callback, it will be wrapped in a gulp `PluginError` and emitted from the stream.
|
|
282
267
|
|
|
283
|
-
Param type: `results => Promise<void>`
|
|
268
|
+
Param type: `(results: Object[]) => Promise<void>`
|
|
284
269
|
|
|
285
270
|
Call an asynchronous, promise-based function once for all ESLint file results before a stream finishes. If the promise is rejected, the rejection reason will be wrapped in a gulp `PluginError` and emitted from the stream.
|
|
286
271
|
|
|
287
|
-
### `
|
|
272
|
+
### `gulpESLintNew.failOnError()`
|
|
288
273
|
|
|
289
274
|
Stop a task/stream if an ESLint error has been reported for any file.
|
|
290
275
|
|
|
291
276
|
```javascript
|
|
292
|
-
// Cause the stream to stop (fail)
|
|
293
|
-
gulp.src(['**/*.js','!node_modules/**'])
|
|
294
|
-
.pipe(
|
|
295
|
-
.pipe(
|
|
277
|
+
// Cause the stream to stop (fail) without processing more files.
|
|
278
|
+
gulp.src(['**/*.js', '!node_modules/**'])
|
|
279
|
+
.pipe(gulpESLintNew())
|
|
280
|
+
.pipe(gulpESLintNew.failOnError());
|
|
296
281
|
```
|
|
297
282
|
|
|
298
|
-
### `
|
|
283
|
+
### `gulpESLintNew.failAfterError()`
|
|
299
284
|
|
|
300
285
|
Stop a task/stream if an ESLint error has been reported for any file, but wait for all of them to be processed first.
|
|
301
286
|
|
|
302
287
|
```javascript
|
|
303
|
-
// Cause the stream to stop(
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
.pipe(
|
|
288
|
+
// Cause the stream to stop (fail) when the stream ends if any ESLint error(s)
|
|
289
|
+
// occurred.
|
|
290
|
+
gulp.src(['**/*.js', '!node_modules/**'])
|
|
291
|
+
.pipe(gulpESLintNew())
|
|
292
|
+
.pipe(gulpESLintNew.failAfterError());
|
|
307
293
|
```
|
|
308
294
|
|
|
309
|
-
### `
|
|
295
|
+
### `gulpESLintNew.format(formatter, output)`
|
|
310
296
|
|
|
311
|
-
Format all linted files once.
|
|
297
|
+
Format all linted files once.
|
|
298
|
+
This should be used in the stream after piping through `gulpESLintNew`; otherwise, this will find no ESLint results to format.
|
|
312
299
|
|
|
313
|
-
The `formatter` argument may be a `string`, `Function`, or `undefined`.
|
|
300
|
+
The `formatter` argument may be a `string`, `Function`, or `undefined`.
|
|
301
|
+
As a `string`, a formatter module by that name or path will be resolved.
|
|
302
|
+
The resolved formatter will be either one of the [built-in ESLint formatters](https://eslint.org/docs/user-guide/formatters/#eslint-formatters), or a formatter exported by a module with the specied path (located relative to the ESLint working directory), or a formatter exported by a package installed as a dependency (the prefix "eslint-formatter-" in the package name can be omitted).
|
|
303
|
+
If `undefined`, the ESLint "stylish" formatter will be resolved.
|
|
304
|
+
A `Function` will be called with an `Array` of file linting results to format.
|
|
314
305
|
|
|
315
306
|
```javascript
|
|
316
|
-
//
|
|
317
|
-
|
|
307
|
+
// Use the default "stylish" ESLint formatter.
|
|
308
|
+
gulpESLintNew.format()
|
|
318
309
|
|
|
319
|
-
//
|
|
320
|
-
|
|
310
|
+
// Use the "checkstyle" ESLint formatter.
|
|
311
|
+
gulpESLintNew.format('checkstyle')
|
|
321
312
|
|
|
322
|
-
//
|
|
323
|
-
//
|
|
324
|
-
|
|
313
|
+
// Use "eslint-formatter-pretty" as a formatter (must be installed with `npm`).
|
|
314
|
+
// See https://github.com/sindresorhus/eslint-formatter-pretty.
|
|
315
|
+
gulpESLintNew.format('pretty')
|
|
325
316
|
```
|
|
326
317
|
|
|
327
|
-
The `output` argument may be a
|
|
318
|
+
The `output` argument may be a writable stream, `Function`, or `undefined`. As a writable stream, the formatter results will be written to the stream.
|
|
319
|
+
If `undefined`, the formatter results will be written to [gulp's log](https://github.com/gulpjs/fancy-log#logmsg).
|
|
320
|
+
A `Function` will be called with the formatter results as the only parameter.
|
|
328
321
|
|
|
329
322
|
```javascript
|
|
330
323
|
// write to gulp's log (default)
|
|
331
|
-
|
|
324
|
+
gulpESLintNew.format()
|
|
332
325
|
|
|
333
326
|
// write messages to stdout
|
|
334
|
-
|
|
327
|
+
gulpESLintNew.format('junit', process.stdout)
|
|
335
328
|
```
|
|
336
329
|
|
|
337
|
-
### `
|
|
330
|
+
### `gulpESLintNew.formatEach(formatter, output)`
|
|
338
331
|
|
|
339
|
-
Format each linted file individually.
|
|
332
|
+
Format each linted file individually.
|
|
333
|
+
This should be used in the stream after piping through `gulpESLintNew`; otherwise, this will find no ESLint results to format.
|
|
340
334
|
|
|
341
335
|
The arguments for `formatEach` are the same as the arguments for `format`.
|
|
342
336
|
|
|
337
|
+
### `gulpESLintNew.fix()`
|
|
338
|
+
|
|
339
|
+
Overwrite files with the fixed content provided by ESLint.
|
|
340
|
+
This should be used in conjunction with the option `fix` in [`gulpESLintNew(options)`](#gulpeslintnewoptions).
|
|
341
|
+
Files without a fixed content will be ignored.
|
|
342
|
+
|
|
343
|
+
```javascript
|
|
344
|
+
gulp.src(['**/*.js', '!node_modules/**'])
|
|
345
|
+
.pipe(gulpESLintNew({ fix: true }))
|
|
346
|
+
.pipe(gulpESLintNew.fix());
|
|
347
|
+
```
|
|
348
|
+
|
|
343
349
|
## Configuration
|
|
344
350
|
|
|
345
351
|
ESLint may be configured explicity by using any of the supported [configuration options](https://eslint.org/docs/user-guide/configuring/). Unless the `useEslintrc` option is set to `false`, ESLint will attempt to resolve a file by the name of `.eslintrc` within the same directory as the file to be linted. If not found there, parent directories will be searched until `.eslintrc` is found or the directory root is reached.
|
|
346
352
|
|
|
347
353
|
## Custom Extensions
|
|
348
354
|
|
|
349
|
-
ESLint results are attached as an `eslint` property to the Vinyl files that pass through a gulp stream pipeline.
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
* [gulp-eslint-if-fixed](https://github.com/lukeapage/gulp-eslint-if-fixed)
|
|
354
|
-
* [gulp-eslint-threshold](https://github.com/krmbkt/gulp-eslint-threshold)
|
|
355
|
+
ESLint results are attached as an `eslint` property to the Vinyl files that pass through a gulp stream pipeline.
|
|
356
|
+
This is available to streams that follow the initial gulp-eslint-new stream.
|
|
357
|
+
The [`gulpESLintNew.result`](#gulpeslintnewresultaction) and [`gulpESLintNew.results`](#gulpeslintnewresultsaction) methods are made available to support extensions and custom handling of ESLint results.
|
|
355
358
|
|
|
359
|
+
[gulp-eslint]: https://github.com/adametry/gulp-eslint
|
|
360
|
+
[linting options]: https://eslint.org/docs/developer-guide/nodejs-api#linting
|
|
356
361
|
[npm badge]: https://badge.fury.io/js/gulp-eslint-new.svg
|
|
357
362
|
[npm URL]: https://www.npmjs.com/package/gulp-eslint-new
|
package/index.js
CHANGED
|
@@ -3,17 +3,18 @@
|
|
|
3
3
|
const {
|
|
4
4
|
createIgnoreResult,
|
|
5
5
|
createPluginError,
|
|
6
|
+
createTransform,
|
|
6
7
|
filterResult,
|
|
7
|
-
|
|
8
|
+
fix,
|
|
8
9
|
hasOwn,
|
|
9
10
|
isErrorMessage,
|
|
10
11
|
migrateOptions,
|
|
11
12
|
resolveWritable,
|
|
12
|
-
createTransform,
|
|
13
13
|
writeResults
|
|
14
14
|
} = require('./util');
|
|
15
15
|
const { ESLint } = require('eslint');
|
|
16
16
|
const { promisify } = require('util');
|
|
17
|
+
const { dest } = require('vinyl-fs');
|
|
17
18
|
|
|
18
19
|
function getESLintInfo(file) {
|
|
19
20
|
const eslintInfo = file._eslintInfo;
|
|
@@ -23,6 +24,16 @@ function getESLintInfo(file) {
|
|
|
23
24
|
throw createPluginError({ fileName: file.path, message: 'ESLint information not available' });
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
function wrapAction(action) {
|
|
28
|
+
if (typeof action !== 'function') {
|
|
29
|
+
throw TypeError('Argument is not a function');
|
|
30
|
+
}
|
|
31
|
+
if (action.length > 1) {
|
|
32
|
+
action = promisify(action);
|
|
33
|
+
}
|
|
34
|
+
return action;
|
|
35
|
+
}
|
|
36
|
+
|
|
26
37
|
async function lintFile(eslintInfo, file, quiet, warnIgnored) {
|
|
27
38
|
if (file.isNull()) {
|
|
28
39
|
return;
|
|
@@ -39,8 +50,6 @@ async function lintFile(eslintInfo, file, quiet, warnIgnored) {
|
|
|
39
50
|
// Note: ESLint doesn't adjust file paths relative to an ancestory .eslintignore path.
|
|
40
51
|
// E.g., If ../.eslintignore has "foo/*.js", ESLint will ignore ./foo/*.js, instead of
|
|
41
52
|
// ../foo/*.js.
|
|
42
|
-
// ESLint rolls this into `ESLint.prototype.lintText`. So, gulp-eslint-new must account for
|
|
43
|
-
// this limitation.
|
|
44
53
|
if (!warnIgnored) {
|
|
45
54
|
return;
|
|
46
55
|
}
|
|
@@ -66,38 +75,28 @@ async function lintFile(eslintInfo, file, quiet, warnIgnored) {
|
|
|
66
75
|
file._eslintInfo = eslintInfo;
|
|
67
76
|
}
|
|
68
77
|
|
|
69
|
-
|
|
78
|
+
module.exports = exports = options => {
|
|
70
79
|
const { eslintOptions, quiet, warnIgnored } = migrateOptions(options);
|
|
71
80
|
const cwd = eslintOptions.cwd || process.cwd();
|
|
72
81
|
const eslint = new ESLint(eslintOptions);
|
|
73
82
|
const eslintInfo = { cwd, eslint };
|
|
74
|
-
return createTransform(
|
|
75
|
-
|
|
76
|
-
);
|
|
77
|
-
}
|
|
83
|
+
return createTransform(file => lintFile(eslintInfo, file, quiet, warnIgnored));
|
|
84
|
+
};
|
|
78
85
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const { eslint } = file;
|
|
88
|
-
if (eslint) {
|
|
89
|
-
await action(eslint);
|
|
86
|
+
exports.result = action => {
|
|
87
|
+
action = wrapAction(action);
|
|
88
|
+
return createTransform(
|
|
89
|
+
async file => {
|
|
90
|
+
const { eslint } = file;
|
|
91
|
+
if (eslint) {
|
|
92
|
+
await action(eslint);
|
|
93
|
+
}
|
|
90
94
|
}
|
|
91
|
-
|
|
95
|
+
);
|
|
92
96
|
};
|
|
93
97
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
throw Error('Expected callable argument');
|
|
97
|
-
}
|
|
98
|
-
if (action.length > 1) {
|
|
99
|
-
action = promisify(action);
|
|
100
|
-
}
|
|
98
|
+
exports.results = action => {
|
|
99
|
+
action = wrapAction(action);
|
|
101
100
|
const results = [];
|
|
102
101
|
results.errorCount = 0;
|
|
103
102
|
results.warningCount = 0;
|
|
@@ -105,8 +104,7 @@ gulpEslint.results = function (action) {
|
|
|
105
104
|
results.fixableWarningCount = 0;
|
|
106
105
|
results.fatalErrorCount = 0;
|
|
107
106
|
return createTransform(
|
|
108
|
-
|
|
109
|
-
const { eslint } = file;
|
|
107
|
+
({ eslint }) => {
|
|
110
108
|
if (eslint) {
|
|
111
109
|
results.push(eslint);
|
|
112
110
|
// Collect total error/warning count.
|
|
@@ -116,52 +114,51 @@ gulpEslint.results = function (action) {
|
|
|
116
114
|
results.fixableWarningCount += eslint.fixableWarningCount;
|
|
117
115
|
results.fatalErrorCount += eslint.fatalErrorCount;
|
|
118
116
|
}
|
|
119
|
-
},
|
|
117
|
+
},
|
|
118
|
+
async () => {
|
|
120
119
|
await action(results);
|
|
121
120
|
}
|
|
122
121
|
);
|
|
123
122
|
};
|
|
124
123
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
124
|
+
exports.failOnError = () => exports.result(result => {
|
|
125
|
+
const { messages } = result;
|
|
126
|
+
if (messages) {
|
|
127
|
+
const error = messages.find(isErrorMessage);
|
|
128
|
+
if (error) {
|
|
129
|
+
throw createPluginError({
|
|
130
|
+
name: 'ESLintError',
|
|
131
|
+
fileName: result.filePath,
|
|
132
|
+
message: error.message,
|
|
133
|
+
lineNumber: error.line
|
|
134
|
+
});
|
|
130
135
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
fileName: result.filePath,
|
|
134
|
-
message: error.message,
|
|
135
|
-
lineNumber: error.line
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
};
|
|
136
|
+
}
|
|
137
|
+
});
|
|
139
138
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const count = results.errorCount;
|
|
143
|
-
if (!count) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
139
|
+
exports.failAfterError = () => exports.results(({ errorCount }) => {
|
|
140
|
+
if (errorCount) {
|
|
146
141
|
throw createPluginError({
|
|
147
142
|
name: 'ESLintError',
|
|
148
|
-
message: `Failed with ${
|
|
143
|
+
message: `Failed with ${errorCount} ${errorCount === 1 ? 'error' : 'errors'}`
|
|
149
144
|
});
|
|
150
|
-
}
|
|
151
|
-
};
|
|
145
|
+
}
|
|
146
|
+
});
|
|
152
147
|
|
|
153
|
-
|
|
148
|
+
exports.formatEach = (formatter, writable) => {
|
|
154
149
|
writable = resolveWritable(writable);
|
|
155
|
-
return createTransform(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
150
|
+
return createTransform(
|
|
151
|
+
async file => {
|
|
152
|
+
const { eslint } = file;
|
|
153
|
+
if (eslint) {
|
|
154
|
+
const eslintInfo = getESLintInfo(file);
|
|
155
|
+
await writeResults([eslint], eslintInfo, formatter, writable);
|
|
156
|
+
}
|
|
160
157
|
}
|
|
161
|
-
|
|
158
|
+
);
|
|
162
159
|
};
|
|
163
160
|
|
|
164
|
-
|
|
161
|
+
exports.format = (formatter, writable) => {
|
|
165
162
|
writable = resolveWritable(writable);
|
|
166
163
|
const results = [];
|
|
167
164
|
let commonInfo;
|
|
@@ -192,4 +189,4 @@ gulpEslint.format = (formatter, writable) => {
|
|
|
192
189
|
);
|
|
193
190
|
};
|
|
194
191
|
|
|
195
|
-
|
|
192
|
+
exports.fix = () => fix(dest);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gulp-eslint-new",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "A gulp plugin to lint code with ESLint 8",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gulpplugin",
|
|
@@ -38,24 +38,26 @@
|
|
|
38
38
|
"test": "mocha --check-leaks test/*.spec.js"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@types/eslint": "^8.
|
|
42
|
-
"@types/node": "^17.0.
|
|
43
|
-
"eslint": "^8.
|
|
41
|
+
"@types/eslint": "^8.4.1",
|
|
42
|
+
"@types/node": "^17.0.13",
|
|
43
|
+
"eslint": "^8.8.0",
|
|
44
44
|
"fancy-log": "^2.0.0",
|
|
45
|
-
"plugin-error": "^1.0.1"
|
|
45
|
+
"plugin-error": "^1.0.1",
|
|
46
|
+
"ternary-stream": "^3.0.0",
|
|
47
|
+
"vinyl-fs": "^3.0.3"
|
|
46
48
|
},
|
|
47
49
|
"devDependencies": {
|
|
48
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
49
|
-
"@typescript-eslint/parser": "^5.
|
|
50
|
+
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
|
51
|
+
"@typescript-eslint/parser": "^5.10.0",
|
|
50
52
|
"c8": "^7.11.0",
|
|
51
53
|
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
52
54
|
"gulp": "^4.0.2",
|
|
53
|
-
"mocha": "^9.1.
|
|
55
|
+
"mocha": "^9.1.4",
|
|
54
56
|
"typescript": "^4.5.4",
|
|
55
57
|
"vinyl": "^2.2.1"
|
|
56
58
|
},
|
|
57
59
|
"engines": {
|
|
58
|
-
"node": ">=12.
|
|
60
|
+
"node": "12 >=12.20 || 14 >=14.13 || >=16"
|
|
59
61
|
},
|
|
60
62
|
"exports": {
|
|
61
63
|
".": "./index.js",
|
package/util.js
CHANGED
|
@@ -4,6 +4,17 @@ const fancyLog = require('fancy-log');
|
|
|
4
4
|
const { relative } = require('path');
|
|
5
5
|
const PluginError = require('plugin-error');
|
|
6
6
|
const { Transform } = require('stream');
|
|
7
|
+
const ternaryStream = require('ternary-stream');
|
|
8
|
+
|
|
9
|
+
function compareResultsByFilePath({ filePath: filePath1 }, { filePath: filePath2 }) {
|
|
10
|
+
if (filePath1 > filePath2) {
|
|
11
|
+
return 1;
|
|
12
|
+
}
|
|
13
|
+
if (filePath1 < filePath2) {
|
|
14
|
+
return -1;
|
|
15
|
+
}
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
7
18
|
|
|
8
19
|
function createPluginError(error) {
|
|
9
20
|
if (error instanceof PluginError) {
|
|
@@ -14,52 +25,80 @@ function createPluginError(error) {
|
|
|
14
25
|
}
|
|
15
26
|
return new PluginError('gulp-eslint-new', error);
|
|
16
27
|
}
|
|
17
|
-
exports.createPluginError = createPluginError;
|
|
18
28
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
const { defineProperty } = Object;
|
|
30
|
+
|
|
31
|
+
/** Determine if the specified object has the indicated property as its own property. */
|
|
32
|
+
const hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Determine if a message is an error.
|
|
36
|
+
*
|
|
37
|
+
* @param {Linter.LintMessage} { severity } - An ESLint message.
|
|
38
|
+
* @returns {boolean} Whether the message is an error message.
|
|
39
|
+
*/
|
|
40
|
+
function isErrorMessage({ severity }) {
|
|
41
|
+
return severity > 1;
|
|
27
42
|
}
|
|
28
43
|
|
|
29
44
|
/**
|
|
30
|
-
*
|
|
31
|
-
* All files are passed through the stream.
|
|
32
|
-
* Errors thrown by the handlers will be wrapped inside a `PluginError` and emitted from the stream.
|
|
45
|
+
* Determine if a message is a warning.
|
|
33
46
|
*
|
|
34
|
-
* @param {
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
* @param {Linter.LintMessage} { severity } - An ESLint message.
|
|
48
|
+
* @returns {boolean} Whether the message is a warning message.
|
|
49
|
+
*/
|
|
50
|
+
function isWarningMessage({ severity }) {
|
|
51
|
+
return severity === 1;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Resolve formatter from string.
|
|
56
|
+
* If a function is specified, it will be treated as an ESLint 6 style formatter function and
|
|
57
|
+
* wrapped into an object appropriately.
|
|
38
58
|
*
|
|
39
|
-
* @param {
|
|
40
|
-
*
|
|
41
|
-
* If the function returns a promise, the stream will be closed after the promise is resolved.
|
|
59
|
+
* @param {{ cwd: string, eslint: ESLint }} eslintInfo
|
|
60
|
+
* Current directory and instance of ESLint used to load and configure the formatter.
|
|
42
61
|
*
|
|
43
|
-
* @
|
|
62
|
+
* @param {string|Function} [formatter]
|
|
63
|
+
* A name or path of a formatter, or an ESLint 6 style formatter function to resolve as a formatter.
|
|
64
|
+
*
|
|
65
|
+
* @returns {Promise<ESLint.Formatter>} An ESLint formatter.
|
|
44
66
|
*/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
67
|
+
function resolveFormatter({ cwd, eslint }, formatter) {
|
|
68
|
+
if (typeof formatter === 'function') {
|
|
69
|
+
return {
|
|
70
|
+
format: results => {
|
|
71
|
+
results.sort(compareResultsByFilePath);
|
|
72
|
+
return formatter(
|
|
73
|
+
results,
|
|
74
|
+
{
|
|
75
|
+
cwd,
|
|
76
|
+
get rulesMeta() {
|
|
77
|
+
const rulesMeta = eslint.getRulesMetaForResults(results);
|
|
78
|
+
defineProperty(this, 'rulesMeta', { value: rulesMeta });
|
|
79
|
+
return rulesMeta;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// Use ESLint to look up formatter references.
|
|
87
|
+
return eslint.loadFormatter(formatter);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
exports.compareResultsByFilePath = compareResultsByFilePath;
|
|
50
91
|
|
|
51
92
|
const isHiddenRegExp = /(?<![^/\\])\.(?!\.)/u;
|
|
52
93
|
const isInNodeModulesRegExp = /(?<![^/\\])node_modules[/\\]/u;
|
|
53
94
|
|
|
54
95
|
/**
|
|
55
|
-
* This is a remake of the CLI
|
|
56
|
-
*
|
|
57
|
-
* Additionally, this function addresses an issue in ESLint that consists in the property
|
|
58
|
-
* `fatalErrorCount` not being set in the result.
|
|
96
|
+
* This is a remake of the CLI engine `createIgnoreResult` function with no reference to ESLint CLI
|
|
97
|
+
* options and with a better detection of the ignore reason in some edge cases.
|
|
59
98
|
*
|
|
60
99
|
* @param {string} filePath - Absolute path of checked code file.
|
|
61
100
|
* @param {string} baseDir - Absolute path of base directory.
|
|
62
|
-
* @returns {LintResult} Result with warning by ignore settings.
|
|
101
|
+
* @returns {ESLint.LintResult} Result with warning by ignore settings.
|
|
63
102
|
*/
|
|
64
103
|
exports.createIgnoreResult = (filePath, baseDir) => {
|
|
65
104
|
let message;
|
|
@@ -88,10 +127,134 @@ exports.createIgnoreResult = (filePath, baseDir) => {
|
|
|
88
127
|
};
|
|
89
128
|
};
|
|
90
129
|
|
|
91
|
-
|
|
92
|
-
|
|
130
|
+
exports.createPluginError = createPluginError;
|
|
131
|
+
|
|
132
|
+
async function awaitHandler(handler, data, done) {
|
|
133
|
+
try {
|
|
134
|
+
await handler();
|
|
135
|
+
} catch (err) {
|
|
136
|
+
done(createPluginError(err));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
done(null, data);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Create a transform stream in object mode from synchronous or asynchronous handler functions.
|
|
144
|
+
* All files are passed through the stream.
|
|
145
|
+
* Errors thrown by the handlers will be wrapped inside a `PluginError` and emitted from the stream.
|
|
146
|
+
*
|
|
147
|
+
* @param {Function} handleFile
|
|
148
|
+
* A function that is called for each file, with the file object as the only parameter.
|
|
149
|
+
* If the function returns a promise, the file will be passed through the stream after the promise
|
|
150
|
+
* is resolved.
|
|
151
|
+
*
|
|
152
|
+
* @param {Function} [handleFinal]
|
|
153
|
+
* A function that is called with no parameters before closing the stream.
|
|
154
|
+
* If the function returns a promise, the stream will be closed after the promise is resolved.
|
|
155
|
+
*
|
|
156
|
+
* @returns {Stream} A transform stream.
|
|
157
|
+
*/
|
|
158
|
+
exports.createTransform = (handleFile, handleFinal) => {
|
|
159
|
+
const transform = (file, enc, done) => void awaitHandler(() => handleFile(file), file, done);
|
|
160
|
+
const final = handleFinal ? done => void awaitHandler(handleFinal, null, done) : undefined;
|
|
161
|
+
return new Transform({ objectMode: true, transform, final });
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Increment count if message is an error.
|
|
166
|
+
*
|
|
167
|
+
* @param {number} count - Number of errors.
|
|
168
|
+
* @param {Linter.LintMessage} message - An ESLint message.
|
|
169
|
+
* @returns {number} The number of errors, message included.
|
|
170
|
+
*/
|
|
171
|
+
function countErrorMessage(count, message) {
|
|
172
|
+
return count + Number(isErrorMessage(message));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Increment count if message is a warning.
|
|
177
|
+
*
|
|
178
|
+
* @param {number} count - Number of warnings.
|
|
179
|
+
* @param {Linter.LintMessage} message - An ESLint message.
|
|
180
|
+
* @returns {number} The number of warnings, message included.
|
|
181
|
+
*/
|
|
182
|
+
function countWarningMessage(count, message) {
|
|
183
|
+
return count + Number(isWarningMessage(message));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Increment count if message is a fixable error.
|
|
188
|
+
*
|
|
189
|
+
* @param {number} count - Number of fixable errors.
|
|
190
|
+
* @param {Linter.LintMessage} message - An ESLint message.
|
|
191
|
+
* @returns {number} The number of fixable errors, message included.
|
|
192
|
+
*/
|
|
193
|
+
function countFixableErrorMessage(count, message) {
|
|
194
|
+
return count + Number(isErrorMessage(message) && message.fix !== undefined);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Increment count if message is a fixable warning.
|
|
199
|
+
*
|
|
200
|
+
* @param {Number} count - Number of fixable warnings.
|
|
201
|
+
* @param {Linter.LintMessage} message - An ESLint message.
|
|
202
|
+
* @returns {Number} The number of fixable warnings, message included.
|
|
203
|
+
*/
|
|
204
|
+
function countFixableWarningMessage(count, message) {
|
|
205
|
+
return count + Number(isWarningMessage(message) && message.fix !== undefined);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Increment count if message is a fatal error.
|
|
210
|
+
*
|
|
211
|
+
* @param {Number} count - Number of fatal errors.
|
|
212
|
+
* @param {Linter.LintMessage} message - An ESLint message.
|
|
213
|
+
* @returns {Number} The number of fatal errors, message included.
|
|
214
|
+
*/
|
|
215
|
+
function countFatalErrorMessage(count, message) {
|
|
216
|
+
return count + Number(isErrorMessage(message) && !!message.fatal);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Filter result messages, update error and warning counts.
|
|
221
|
+
*
|
|
222
|
+
* @param {ESLint.LintResult} result - An ESLint result.
|
|
223
|
+
* @param {Function} filter - A function that evaluates what messages to keep.
|
|
224
|
+
* @returns {ESLint.LintResult} A filtered ESLint result.
|
|
225
|
+
*/
|
|
226
|
+
exports.filterResult = (result, filter) => {
|
|
227
|
+
const { messages, ...newResult } = result;
|
|
228
|
+
const newMessages = messages.filter(filter, result);
|
|
229
|
+
newResult.messages = newMessages;
|
|
230
|
+
newResult.errorCount = newMessages.reduce(countErrorMessage, 0);
|
|
231
|
+
newResult.warningCount = newMessages.reduce(countWarningMessage, 0);
|
|
232
|
+
newResult.fixableErrorCount = newMessages.reduce(countFixableErrorMessage, 0);
|
|
233
|
+
newResult.fixableWarningCount = newMessages.reduce(countFixableWarningMessage, 0);
|
|
234
|
+
newResult.fatalErrorCount = newMessages.reduce(countFatalErrorMessage, 0);
|
|
235
|
+
return newResult;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const isFixed = ({ eslint }) => eslint && eslint.fixed;
|
|
239
|
+
const getBase = ({ base }) => base;
|
|
240
|
+
exports.fix = dest => ternaryStream(isFixed, dest(getBase));
|
|
241
|
+
|
|
93
242
|
exports.hasOwn = hasOwn;
|
|
94
243
|
|
|
244
|
+
exports.isErrorMessage = isErrorMessage;
|
|
245
|
+
|
|
246
|
+
exports.isWarningMessage = isWarningMessage;
|
|
247
|
+
|
|
248
|
+
const forbiddenOptions = [
|
|
249
|
+
'cache',
|
|
250
|
+
'cacheFile',
|
|
251
|
+
'cacheLocation',
|
|
252
|
+
'cacheStrategy',
|
|
253
|
+
'errorOnUnmatchedPattern',
|
|
254
|
+
'extensions',
|
|
255
|
+
'globInputPaths'
|
|
256
|
+
];
|
|
257
|
+
|
|
95
258
|
/**
|
|
96
259
|
* Throws an error about invalid options passed to gulp-eslint-new.
|
|
97
260
|
*
|
|
@@ -131,20 +294,10 @@ function toBooleanMap(keys, defaultValue, displayName) {
|
|
|
131
294
|
}
|
|
132
295
|
}
|
|
133
296
|
|
|
134
|
-
const forbiddenOptions = [
|
|
135
|
-
'cache',
|
|
136
|
-
'cacheFile',
|
|
137
|
-
'cacheLocation',
|
|
138
|
-
'cacheStrategy',
|
|
139
|
-
'errorOnUnmatchedPattern',
|
|
140
|
-
'extensions',
|
|
141
|
-
'globInputPaths'
|
|
142
|
-
];
|
|
143
|
-
|
|
144
297
|
/**
|
|
145
298
|
* Create config helper to merge various config sources.
|
|
146
299
|
*
|
|
147
|
-
* @param {Object} options - Options to migrate.
|
|
300
|
+
* @param {Object} [options] - Options to migrate.
|
|
148
301
|
* @returns {Object} Migrated options.
|
|
149
302
|
*/
|
|
150
303
|
exports.migrateOptions = (options = { }) => {
|
|
@@ -202,174 +355,6 @@ exports.migrateOptions = (options = { }) => {
|
|
|
202
355
|
return returnValue;
|
|
203
356
|
};
|
|
204
357
|
|
|
205
|
-
/**
|
|
206
|
-
* Get first message in an ESLint result to meet a condition.
|
|
207
|
-
*
|
|
208
|
-
* @param {LintResult} result
|
|
209
|
-
* An ESLint result.
|
|
210
|
-
* @param {Function} condition
|
|
211
|
-
* A condition function that is passed a message and returns a boolean.
|
|
212
|
-
* @returns {Object} The first message to pass the condition or null.
|
|
213
|
-
*/
|
|
214
|
-
exports.firstResultMessage = (result, condition) => {
|
|
215
|
-
if (!result.messages) {
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
return result.messages.find(condition);
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Determine if a message is an error.
|
|
223
|
-
*
|
|
224
|
-
* @param {Object} message - An ESLint message.
|
|
225
|
-
* @returns {boolean} Whether the message is an error message.
|
|
226
|
-
*/
|
|
227
|
-
function isErrorMessage({ severity }) {
|
|
228
|
-
return severity > 1;
|
|
229
|
-
}
|
|
230
|
-
exports.isErrorMessage = isErrorMessage;
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Determine if a message is a warning.
|
|
234
|
-
*
|
|
235
|
-
* @param {Object} message - An ESLint message.
|
|
236
|
-
* @returns {boolean} Whether the message is a warning message.
|
|
237
|
-
*/
|
|
238
|
-
function isWarningMessage({ severity }) {
|
|
239
|
-
return severity === 1;
|
|
240
|
-
}
|
|
241
|
-
exports.isWarningMessage = isWarningMessage;
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Increment count if message is an error.
|
|
245
|
-
*
|
|
246
|
-
* @param {number} count - Number of errors.
|
|
247
|
-
* @param {Object} message - An ESLint message.
|
|
248
|
-
* @returns {number} The number of errors, message included.
|
|
249
|
-
*/
|
|
250
|
-
function countErrorMessage(count, message) {
|
|
251
|
-
return count + Number(isErrorMessage(message));
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Increment count if message is a warning.
|
|
256
|
-
*
|
|
257
|
-
* @param {number} count - Number of warnings.
|
|
258
|
-
* @param {Object} message - An ESLint message.
|
|
259
|
-
* @returns {number} The number of warnings, message included.
|
|
260
|
-
*/
|
|
261
|
-
function countWarningMessage(count, message) {
|
|
262
|
-
return count + Number(isWarningMessage(message));
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Increment count if message is a fixable error.
|
|
267
|
-
*
|
|
268
|
-
* @param {number} count - Number of fixable errors.
|
|
269
|
-
* @param {Object} message - An ESLint message.
|
|
270
|
-
* @returns {number} The number of fixable errors, message included.
|
|
271
|
-
*/
|
|
272
|
-
function countFixableErrorMessage(count, message) {
|
|
273
|
-
return count + Number(isErrorMessage(message) && message.fix !== undefined);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Increment count if message is a fixable warning.
|
|
278
|
-
*
|
|
279
|
-
* @param {Number} count - Number of fixable warnings.
|
|
280
|
-
* @param {Object} message - An ESLint message.
|
|
281
|
-
* @returns {Number} The number of fixable warnings, message included.
|
|
282
|
-
*/
|
|
283
|
-
function countFixableWarningMessage(count, message) {
|
|
284
|
-
return count + Number(isWarningMessage(message) && message.fix !== undefined);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Increment count if message is a fatal error.
|
|
289
|
-
*
|
|
290
|
-
* @param {Number} count - Number of fatal errors.
|
|
291
|
-
* @param {Object} message - An ESLint message.
|
|
292
|
-
* @returns {Number} The number of fatal errors, message included.
|
|
293
|
-
*/
|
|
294
|
-
function countFatalErrorMessage(count, message) {
|
|
295
|
-
return count + Number(isErrorMessage(message) && !!message.fatal);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Filter result messages, update error and warning counts.
|
|
300
|
-
*
|
|
301
|
-
* @param {LintResult} result - An ESLint result.
|
|
302
|
-
* @param {Function} filter - A function that evaluates what messages to keep.
|
|
303
|
-
* @returns {LintResult} A filtered ESLint result.
|
|
304
|
-
*/
|
|
305
|
-
exports.filterResult = (result, filter) => {
|
|
306
|
-
const messages = result.messages.filter(filter, result);
|
|
307
|
-
const newResult = {
|
|
308
|
-
filePath: result.filePath,
|
|
309
|
-
messages: messages,
|
|
310
|
-
errorCount: messages.reduce(countErrorMessage, 0),
|
|
311
|
-
warningCount: messages.reduce(countWarningMessage, 0),
|
|
312
|
-
fixableErrorCount: messages.reduce(countFixableErrorMessage, 0),
|
|
313
|
-
fixableWarningCount: messages.reduce(countFixableWarningMessage, 0),
|
|
314
|
-
fatalErrorCount: messages.reduce(countFatalErrorMessage, 0)
|
|
315
|
-
};
|
|
316
|
-
if ('output' in result) {
|
|
317
|
-
newResult.output = result.output;
|
|
318
|
-
}
|
|
319
|
-
if ('source' in result) {
|
|
320
|
-
newResult.source = result.source;
|
|
321
|
-
}
|
|
322
|
-
return newResult;
|
|
323
|
-
};
|
|
324
|
-
|
|
325
|
-
function compareResultsByFilePath({ filePath: filePath1 }, { filePath: filePath2 }) {
|
|
326
|
-
if (filePath1 > filePath2) {
|
|
327
|
-
return 1;
|
|
328
|
-
}
|
|
329
|
-
if (filePath1 < filePath2) {
|
|
330
|
-
return -1;
|
|
331
|
-
}
|
|
332
|
-
return 0;
|
|
333
|
-
}
|
|
334
|
-
exports.compareResultsByFilePath = compareResultsByFilePath;
|
|
335
|
-
|
|
336
|
-
const { defineProperty } = Object;
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Resolve formatter from string.
|
|
340
|
-
* If a function is specified, it will be treated as an ESLint 6 style formatter function and
|
|
341
|
-
* wrapped into an object appropriately.
|
|
342
|
-
*
|
|
343
|
-
* @param {{ cwd: string, eslint: ESLint }} eslintInfo
|
|
344
|
-
* Current directory and instance of ESLint used to load and configure the formatter.
|
|
345
|
-
*
|
|
346
|
-
* @param {string|Function} [formatter]
|
|
347
|
-
* A name or path of a formatter, or an ESLint 6 style formatter function to resolve as a formatter.
|
|
348
|
-
*
|
|
349
|
-
* @returns {Promise<ESLint.Formatter>} An ESLint formatter.
|
|
350
|
-
*/
|
|
351
|
-
async function resolveFormatter({ cwd, eslint }, formatter) {
|
|
352
|
-
if (typeof formatter === 'function') {
|
|
353
|
-
return {
|
|
354
|
-
format: results => {
|
|
355
|
-
results.sort(compareResultsByFilePath);
|
|
356
|
-
return formatter(
|
|
357
|
-
results,
|
|
358
|
-
{
|
|
359
|
-
cwd,
|
|
360
|
-
get rulesMeta() {
|
|
361
|
-
const rulesMeta = eslint.getRulesMetaForResults(results);
|
|
362
|
-
defineProperty(this, 'rulesMeta', { value: rulesMeta });
|
|
363
|
-
return rulesMeta;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
);
|
|
367
|
-
}
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
// Use ESLint to look up formatter references.
|
|
371
|
-
return eslint.loadFormatter(formatter);
|
|
372
|
-
}
|
|
373
358
|
exports.resolveFormatter = resolveFormatter;
|
|
374
359
|
|
|
375
360
|
/**
|