eslint 6.6.0 → 6.8.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/CHANGELOG.md +94 -0
- package/README.md +7 -8
- package/conf/config-schema.js +2 -0
- package/conf/default-cli-options.js +1 -1
- package/conf/eslint-recommended.js +0 -1
- package/lib/cli-engine/cascading-config-array-factory.js +38 -13
- package/lib/cli-engine/cli-engine.js +41 -14
- package/lib/cli-engine/config-array/config-array.js +13 -0
- package/lib/cli-engine/config-array/extracted-config.js +27 -0
- package/lib/cli-engine/config-array/ignore-pattern.js +231 -0
- package/lib/cli-engine/config-array/index.js +2 -0
- package/lib/cli-engine/config-array-factory.js +115 -1
- package/lib/cli-engine/file-enumerator.js +73 -40
- package/lib/cli-engine/lint-result-cache.js +2 -1
- package/lib/cli.js +2 -1
- package/lib/init/config-initializer.js +4 -3
- package/lib/linter/config-comment-parser.js +1 -1
- package/lib/linter/report-translator.js +73 -7
- package/lib/options.js +6 -0
- package/lib/rule-tester/rule-tester.js +42 -6
- package/lib/rules/array-bracket-spacing.js +8 -8
- package/lib/rules/camelcase.js +19 -6
- package/lib/rules/comma-dangle.js +5 -2
- package/lib/rules/computed-property-spacing.js +4 -4
- package/lib/rules/curly.js +9 -4
- package/lib/rules/function-call-argument-newline.js +3 -1
- package/lib/rules/grouped-accessor-pairs.js +224 -0
- package/lib/rules/indent.js +11 -0
- package/lib/rules/index.js +5 -0
- package/lib/rules/key-spacing.js +34 -15
- package/lib/rules/lines-between-class-members.js +42 -53
- package/lib/rules/multiline-comment-style.js +237 -106
- package/lib/rules/no-cond-assign.js +14 -4
- package/lib/rules/no-constructor-return.js +62 -0
- package/lib/rules/no-dupe-else-if.js +122 -0
- package/lib/rules/no-implicit-globals.js +90 -8
- package/lib/rules/no-inline-comments.js +25 -11
- package/lib/rules/no-invalid-this.js +16 -2
- package/lib/rules/no-multiple-empty-lines.js +1 -1
- package/lib/rules/no-octal-escape.js +1 -1
- package/lib/rules/no-restricted-imports.js +2 -2
- package/lib/rules/no-setter-return.js +227 -0
- package/lib/rules/no-underscore-dangle.js +23 -4
- package/lib/rules/no-unexpected-multiline.js +8 -0
- package/lib/rules/no-unsafe-negation.js +30 -5
- package/lib/rules/no-useless-computed-key.js +60 -33
- package/lib/rules/no-useless-escape.js +26 -3
- package/lib/rules/object-curly-spacing.js +8 -8
- package/lib/rules/operator-assignment.js +11 -2
- package/lib/rules/prefer-const.js +14 -7
- package/lib/rules/prefer-exponentiation-operator.js +189 -0
- package/lib/rules/prefer-numeric-literals.js +29 -28
- package/lib/rules/require-atomic-updates.js +1 -1
- package/lib/rules/require-await.js +8 -0
- package/lib/rules/semi.js +6 -3
- package/lib/rules/space-infix-ops.js +1 -1
- package/lib/rules/spaced-comment.js +5 -4
- package/lib/rules/utils/ast-utils.js +31 -4
- package/lib/shared/types.js +9 -0
- package/lib/source-code/source-code.js +87 -10
- package/package.json +4 -3
- package/lib/cli-engine/ignored-paths.js +0 -363
@@ -0,0 +1,231 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview `IgnorePattern` class.
|
3
|
+
*
|
4
|
+
* `IgnorePattern` class has the set of glob patterns and the base path.
|
5
|
+
*
|
6
|
+
* It provides two static methods.
|
7
|
+
*
|
8
|
+
* - `IgnorePattern.createDefaultIgnore(cwd)`
|
9
|
+
* Create the default predicate function.
|
10
|
+
* - `IgnorePattern.createIgnore(ignorePatterns)`
|
11
|
+
* Create the predicate function from multiple `IgnorePattern` objects.
|
12
|
+
*
|
13
|
+
* It provides two properties and a method.
|
14
|
+
*
|
15
|
+
* - `patterns`
|
16
|
+
* The glob patterns that ignore to lint.
|
17
|
+
* - `basePath`
|
18
|
+
* The base path of the glob patterns. If absolute paths existed in the
|
19
|
+
* glob patterns, those are handled as relative paths to the base path.
|
20
|
+
* - `getPatternsRelativeTo(basePath)`
|
21
|
+
* Get `patterns` as modified for a given base path. It modifies the
|
22
|
+
* absolute paths in the patterns as prepending the difference of two base
|
23
|
+
* paths.
|
24
|
+
*
|
25
|
+
* `ConfigArrayFactory` creates `IgnorePattern` objects when it processes
|
26
|
+
* `ignorePatterns` properties.
|
27
|
+
*
|
28
|
+
* @author Toru Nagashima <https://github.com/mysticatea>
|
29
|
+
*/
|
30
|
+
"use strict";
|
31
|
+
|
32
|
+
//------------------------------------------------------------------------------
|
33
|
+
// Requirements
|
34
|
+
//------------------------------------------------------------------------------
|
35
|
+
|
36
|
+
const assert = require("assert");
|
37
|
+
const path = require("path");
|
38
|
+
const ignore = require("ignore");
|
39
|
+
const debug = require("debug")("eslint:ignore-pattern");
|
40
|
+
|
41
|
+
/** @typedef {ReturnType<import("ignore").default>} Ignore */
|
42
|
+
|
43
|
+
//------------------------------------------------------------------------------
|
44
|
+
// Helpers
|
45
|
+
//------------------------------------------------------------------------------
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Get the path to the common ancestor directory of given paths.
|
49
|
+
* @param {string[]} sourcePaths The paths to calculate the common ancestor.
|
50
|
+
* @returns {string} The path to the common ancestor directory.
|
51
|
+
*/
|
52
|
+
function getCommonAncestorPath(sourcePaths) {
|
53
|
+
let result = sourcePaths[0];
|
54
|
+
|
55
|
+
for (let i = 1; i < sourcePaths.length; ++i) {
|
56
|
+
const a = result;
|
57
|
+
const b = sourcePaths[i];
|
58
|
+
|
59
|
+
// Set the shorter one (it's the common ancestor if one includes the other).
|
60
|
+
result = a.length < b.length ? a : b;
|
61
|
+
|
62
|
+
// Set the common ancestor.
|
63
|
+
for (let j = 0, lastSepPos = 0; j < a.length && j < b.length; ++j) {
|
64
|
+
if (a[j] !== b[j]) {
|
65
|
+
result = a.slice(0, lastSepPos);
|
66
|
+
break;
|
67
|
+
}
|
68
|
+
if (a[j] === path.sep) {
|
69
|
+
lastSepPos = j;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
return result || path.sep;
|
75
|
+
}
|
76
|
+
|
77
|
+
/**
|
78
|
+
* Make relative path.
|
79
|
+
* @param {string} from The source path to get relative path.
|
80
|
+
* @param {string} to The destination path to get relative path.
|
81
|
+
* @returns {string} The relative path.
|
82
|
+
*/
|
83
|
+
function relative(from, to) {
|
84
|
+
const relPath = path.relative(from, to);
|
85
|
+
|
86
|
+
if (path.sep === "/") {
|
87
|
+
return relPath;
|
88
|
+
}
|
89
|
+
return relPath.split(path.sep).join("/");
|
90
|
+
}
|
91
|
+
|
92
|
+
/**
|
93
|
+
* Get the trailing slash if existed.
|
94
|
+
* @param {string} filePath The path to check.
|
95
|
+
* @returns {string} The trailing slash if existed.
|
96
|
+
*/
|
97
|
+
function dirSuffix(filePath) {
|
98
|
+
const isDir = (
|
99
|
+
filePath.endsWith(path.sep) ||
|
100
|
+
(process.platform === "win32" && filePath.endsWith("/"))
|
101
|
+
);
|
102
|
+
|
103
|
+
return isDir ? "/" : "";
|
104
|
+
}
|
105
|
+
|
106
|
+
const DefaultPatterns = Object.freeze(["/node_modules/*", "/bower_components/*"]);
|
107
|
+
const DotPatterns = Object.freeze([".*", "!../"]);
|
108
|
+
|
109
|
+
//------------------------------------------------------------------------------
|
110
|
+
// Public
|
111
|
+
//------------------------------------------------------------------------------
|
112
|
+
|
113
|
+
class IgnorePattern {
|
114
|
+
|
115
|
+
/**
|
116
|
+
* The default patterns.
|
117
|
+
* @type {string[]}
|
118
|
+
*/
|
119
|
+
static get DefaultPatterns() {
|
120
|
+
return DefaultPatterns;
|
121
|
+
}
|
122
|
+
|
123
|
+
/**
|
124
|
+
* Create the default predicate function.
|
125
|
+
* @param {string} cwd The current working directory.
|
126
|
+
* @returns {((filePath:string, dot:boolean) => boolean) & {basePath:string; patterns:string[]}}
|
127
|
+
* The preficate function.
|
128
|
+
* The first argument is an absolute path that is checked.
|
129
|
+
* The second argument is the flag to not ignore dotfiles.
|
130
|
+
* If the predicate function returned `true`, it means the path should be ignored.
|
131
|
+
*/
|
132
|
+
static createDefaultIgnore(cwd) {
|
133
|
+
return this.createIgnore([new IgnorePattern(DefaultPatterns, cwd)]);
|
134
|
+
}
|
135
|
+
|
136
|
+
/**
|
137
|
+
* Create the predicate function from multiple `IgnorePattern` objects.
|
138
|
+
* @param {IgnorePattern[]} ignorePatterns The list of ignore patterns.
|
139
|
+
* @returns {((filePath:string, dot?:boolean) => boolean) & {basePath:string; patterns:string[]}}
|
140
|
+
* The preficate function.
|
141
|
+
* The first argument is an absolute path that is checked.
|
142
|
+
* The second argument is the flag to not ignore dotfiles.
|
143
|
+
* If the predicate function returned `true`, it means the path should be ignored.
|
144
|
+
*/
|
145
|
+
static createIgnore(ignorePatterns) {
|
146
|
+
debug("Create with: %o", ignorePatterns);
|
147
|
+
|
148
|
+
const basePath = getCommonAncestorPath(ignorePatterns.map(p => p.basePath));
|
149
|
+
const patterns = [].concat(
|
150
|
+
...ignorePatterns.map(p => p.getPatternsRelativeTo(basePath))
|
151
|
+
);
|
152
|
+
const ig = ignore().add([...DotPatterns, ...patterns]);
|
153
|
+
const dotIg = ignore().add(patterns);
|
154
|
+
|
155
|
+
debug(" processed: %o", { basePath, patterns });
|
156
|
+
|
157
|
+
return Object.assign(
|
158
|
+
(filePath, dot = false) => {
|
159
|
+
assert(path.isAbsolute(filePath), "'filePath' should be an absolute path.");
|
160
|
+
const relPathRaw = relative(basePath, filePath);
|
161
|
+
const relPath = relPathRaw && (relPathRaw + dirSuffix(filePath));
|
162
|
+
const adoptedIg = dot ? dotIg : ig;
|
163
|
+
const result = relPath !== "" && adoptedIg.ignores(relPath);
|
164
|
+
|
165
|
+
debug("Check", { filePath, dot, relativePath: relPath, result });
|
166
|
+
return result;
|
167
|
+
},
|
168
|
+
{ basePath, patterns }
|
169
|
+
);
|
170
|
+
}
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Initialize a new `IgnorePattern` instance.
|
174
|
+
* @param {string[]} patterns The glob patterns that ignore to lint.
|
175
|
+
* @param {string} basePath The base path of `patterns`.
|
176
|
+
*/
|
177
|
+
constructor(patterns, basePath) {
|
178
|
+
assert(path.isAbsolute(basePath), "'basePath' should be an absolute path.");
|
179
|
+
|
180
|
+
/**
|
181
|
+
* The glob patterns that ignore to lint.
|
182
|
+
* @type {string[]}
|
183
|
+
*/
|
184
|
+
this.patterns = patterns;
|
185
|
+
|
186
|
+
/**
|
187
|
+
* The base path of `patterns`.
|
188
|
+
* @type {string}
|
189
|
+
*/
|
190
|
+
this.basePath = basePath;
|
191
|
+
|
192
|
+
/**
|
193
|
+
* If `true` then patterns which don't start with `/` will match the paths to the outside of `basePath`. Defaults to `false`.
|
194
|
+
*
|
195
|
+
* It's set `true` for `.eslintignore`, `package.json`, and `--ignore-path` for backward compatibility.
|
196
|
+
* It's `false` as-is for `ignorePatterns` property in config files.
|
197
|
+
* @type {boolean}
|
198
|
+
*/
|
199
|
+
this.loose = false;
|
200
|
+
}
|
201
|
+
|
202
|
+
/**
|
203
|
+
* Get `patterns` as modified for a given base path. It modifies the
|
204
|
+
* absolute paths in the patterns as prepending the difference of two base
|
205
|
+
* paths.
|
206
|
+
* @param {string} newBasePath The base path.
|
207
|
+
* @returns {string[]} Modifired patterns.
|
208
|
+
*/
|
209
|
+
getPatternsRelativeTo(newBasePath) {
|
210
|
+
assert(path.isAbsolute(newBasePath), "'newBasePath' should be an absolute path.");
|
211
|
+
const { basePath, loose, patterns } = this;
|
212
|
+
|
213
|
+
if (newBasePath === basePath) {
|
214
|
+
return patterns;
|
215
|
+
}
|
216
|
+
const prefix = `/${relative(newBasePath, basePath)}`;
|
217
|
+
|
218
|
+
return patterns.map(pattern => {
|
219
|
+
const negative = pattern.startsWith("!");
|
220
|
+
const head = negative ? "!" : "";
|
221
|
+
const body = negative ? pattern.slice(1) : pattern;
|
222
|
+
|
223
|
+
if (body.startsWith("/") || body.startsWith("../")) {
|
224
|
+
return `${head}${prefix}${body}`;
|
225
|
+
}
|
226
|
+
return loose ? pattern : `${head}${prefix}/**/${body}`;
|
227
|
+
});
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
module.exports = { IgnorePattern };
|
@@ -7,12 +7,14 @@
|
|
7
7
|
const { ConfigArray, getUsedExtractedConfigs } = require("./config-array");
|
8
8
|
const { ConfigDependency } = require("./config-dependency");
|
9
9
|
const { ExtractedConfig } = require("./extracted-config");
|
10
|
+
const { IgnorePattern } = require("./ignore-pattern");
|
10
11
|
const { OverrideTester } = require("./override-tester");
|
11
12
|
|
12
13
|
module.exports = {
|
13
14
|
ConfigArray,
|
14
15
|
ConfigDependency,
|
15
16
|
ExtractedConfig,
|
17
|
+
IgnorePattern,
|
16
18
|
OverrideTester,
|
17
19
|
getUsedExtractedConfigs
|
18
20
|
};
|
@@ -17,6 +17,12 @@
|
|
17
17
|
* Create a `ConfigArray` instance from a config file which is on a given
|
18
18
|
* directory. This tries to load `.eslintrc.*` or `package.json`. If not
|
19
19
|
* found, returns an empty `ConfigArray`.
|
20
|
+
* - `loadESLintIgnore(filePath)`
|
21
|
+
* Create a `ConfigArray` instance from a config file that is `.eslintignore`
|
22
|
+
* format. This is to handle `--ignore-path` option.
|
23
|
+
* - `loadDefaultESLintIgnore()`
|
24
|
+
* Create a `ConfigArray` instance from `.eslintignore` or `package.json` in
|
25
|
+
* the current working directory.
|
20
26
|
*
|
21
27
|
* `ConfigArrayFactory` class has the responsibility that loads configuration
|
22
28
|
* files, including loading `extends`, `parser`, and `plugins`. The created
|
@@ -40,7 +46,12 @@ const stripComments = require("strip-json-comments");
|
|
40
46
|
const { validateConfigSchema } = require("../shared/config-validator");
|
41
47
|
const naming = require("../shared/naming");
|
42
48
|
const ModuleResolver = require("../shared/relative-module-resolver");
|
43
|
-
const {
|
49
|
+
const {
|
50
|
+
ConfigArray,
|
51
|
+
ConfigDependency,
|
52
|
+
IgnorePattern,
|
53
|
+
OverrideTester
|
54
|
+
} = require("./config-array");
|
44
55
|
const debug = require("debug")("eslint:config-array-factory");
|
45
56
|
|
46
57
|
//------------------------------------------------------------------------------
|
@@ -51,6 +62,7 @@ const eslintRecommendedPath = path.resolve(__dirname, "../../conf/eslint-recomme
|
|
51
62
|
const eslintAllPath = path.resolve(__dirname, "../../conf/eslint-all.js");
|
52
63
|
const configFilenames = [
|
53
64
|
".eslintrc.js",
|
65
|
+
".eslintrc.cjs",
|
54
66
|
".eslintrc.yaml",
|
55
67
|
".eslintrc.yml",
|
56
68
|
".eslintrc.json",
|
@@ -221,6 +233,26 @@ function loadPackageJSONConfigFile(filePath) {
|
|
221
233
|
}
|
222
234
|
}
|
223
235
|
|
236
|
+
/**
|
237
|
+
* Loads a `.eslintignore` from a file.
|
238
|
+
* @param {string} filePath The filename to load.
|
239
|
+
* @returns {string[]} The ignore patterns from the file.
|
240
|
+
* @private
|
241
|
+
*/
|
242
|
+
function loadESLintIgnoreFile(filePath) {
|
243
|
+
debug(`Loading .eslintignore file: ${filePath}`);
|
244
|
+
|
245
|
+
try {
|
246
|
+
return readFile(filePath)
|
247
|
+
.split(/\r?\n/gu)
|
248
|
+
.filter(line => line.trim() !== "" && !line.startsWith("#"));
|
249
|
+
} catch (e) {
|
250
|
+
debug(`Error reading .eslintignore file: ${filePath}`);
|
251
|
+
e.message = `Cannot read .eslintignore file: ${filePath}\nError: ${e.message}`;
|
252
|
+
throw e;
|
253
|
+
}
|
254
|
+
}
|
255
|
+
|
224
256
|
/**
|
225
257
|
* Creates an error to notify about a missing config to extend from.
|
226
258
|
* @param {string} configName The name of the missing config.
|
@@ -248,6 +280,7 @@ function configMissingError(configName, importerName) {
|
|
248
280
|
function loadConfigFile(filePath) {
|
249
281
|
switch (path.extname(filePath)) {
|
250
282
|
case ".js":
|
283
|
+
case ".cjs":
|
251
284
|
return loadJSConfigFile(filePath);
|
252
285
|
|
253
286
|
case ".json":
|
@@ -403,6 +436,54 @@ class ConfigArrayFactory {
|
|
403
436
|
);
|
404
437
|
}
|
405
438
|
|
439
|
+
/**
|
440
|
+
* Load `.eslintignore` file.
|
441
|
+
* @param {string} filePath The path to a `.eslintignore` file to load.
|
442
|
+
* @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist.
|
443
|
+
*/
|
444
|
+
loadESLintIgnore(filePath) {
|
445
|
+
const { cwd } = internalSlotsMap.get(this);
|
446
|
+
const absolutePath = path.resolve(cwd, filePath);
|
447
|
+
const name = path.relative(cwd, absolutePath);
|
448
|
+
const ignorePatterns = loadESLintIgnoreFile(absolutePath);
|
449
|
+
|
450
|
+
return createConfigArray(
|
451
|
+
this._normalizeESLintIgnoreData(ignorePatterns, absolutePath, name)
|
452
|
+
);
|
453
|
+
}
|
454
|
+
|
455
|
+
/**
|
456
|
+
* Load `.eslintignore` file in the current working directory.
|
457
|
+
* @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist.
|
458
|
+
*/
|
459
|
+
loadDefaultESLintIgnore() {
|
460
|
+
const { cwd } = internalSlotsMap.get(this);
|
461
|
+
const eslintIgnorePath = path.resolve(cwd, ".eslintignore");
|
462
|
+
const packageJsonPath = path.resolve(cwd, "package.json");
|
463
|
+
|
464
|
+
if (fs.existsSync(eslintIgnorePath)) {
|
465
|
+
return this.loadESLintIgnore(eslintIgnorePath);
|
466
|
+
}
|
467
|
+
if (fs.existsSync(packageJsonPath)) {
|
468
|
+
const data = loadJSONConfigFile(packageJsonPath);
|
469
|
+
|
470
|
+
if (Object.hasOwnProperty.call(data, "eslintIgnore")) {
|
471
|
+
if (!Array.isArray(data.eslintIgnore)) {
|
472
|
+
throw new Error("Package.json eslintIgnore property requires an array of paths");
|
473
|
+
}
|
474
|
+
return createConfigArray(
|
475
|
+
this._normalizeESLintIgnoreData(
|
476
|
+
data.eslintIgnore,
|
477
|
+
packageJsonPath,
|
478
|
+
"eslintIgnore in package.json"
|
479
|
+
)
|
480
|
+
);
|
481
|
+
}
|
482
|
+
}
|
483
|
+
|
484
|
+
return new ConfigArray();
|
485
|
+
}
|
486
|
+
|
406
487
|
/**
|
407
488
|
* Load a given config file.
|
408
489
|
* @param {string} filePath The path to a config file.
|
@@ -451,6 +532,30 @@ class ConfigArrayFactory {
|
|
451
532
|
return null;
|
452
533
|
}
|
453
534
|
|
535
|
+
/**
|
536
|
+
* Normalize a given `.eslintignore` data to config array elements.
|
537
|
+
* @param {string[]} ignorePatterns The patterns to ignore files.
|
538
|
+
* @param {string|undefined} filePath The file path of this config.
|
539
|
+
* @param {string|undefined} name The name of this config.
|
540
|
+
* @returns {IterableIterator<ConfigArrayElement>} The normalized config.
|
541
|
+
* @private
|
542
|
+
*/
|
543
|
+
*_normalizeESLintIgnoreData(ignorePatterns, filePath, name) {
|
544
|
+
const elements = this._normalizeObjectConfigData(
|
545
|
+
{ ignorePatterns },
|
546
|
+
filePath,
|
547
|
+
name
|
548
|
+
);
|
549
|
+
|
550
|
+
// Set `ignorePattern.loose` flag for backward compatibility.
|
551
|
+
for (const element of elements) {
|
552
|
+
if (element.ignorePattern) {
|
553
|
+
element.ignorePattern.loose = true;
|
554
|
+
}
|
555
|
+
yield element;
|
556
|
+
}
|
557
|
+
}
|
558
|
+
|
454
559
|
/**
|
455
560
|
* Normalize a given config to an array.
|
456
561
|
* @param {ConfigData} configData The config data to normalize.
|
@@ -494,6 +599,9 @@ class ConfigArrayFactory {
|
|
494
599
|
if (element.criteria) {
|
495
600
|
element.criteria.basePath = basePath;
|
496
601
|
}
|
602
|
+
if (element.ignorePattern) {
|
603
|
+
element.ignorePattern.basePath = basePath;
|
604
|
+
}
|
497
605
|
|
498
606
|
/*
|
499
607
|
* Merge the criteria; this is for only file extension processors in
|
@@ -526,6 +634,7 @@ class ConfigArrayFactory {
|
|
526
634
|
env,
|
527
635
|
extends: extend,
|
528
636
|
globals,
|
637
|
+
ignorePatterns,
|
529
638
|
noInlineConfig,
|
530
639
|
parser: parserName,
|
531
640
|
parserOptions,
|
@@ -541,6 +650,10 @@ class ConfigArrayFactory {
|
|
541
650
|
name
|
542
651
|
) {
|
543
652
|
const extendList = Array.isArray(extend) ? extend : [extend];
|
653
|
+
const ignorePattern = ignorePatterns && new IgnorePattern(
|
654
|
+
Array.isArray(ignorePatterns) ? ignorePatterns : [ignorePatterns],
|
655
|
+
filePath ? path.dirname(filePath) : internalSlotsMap.get(this).cwd
|
656
|
+
);
|
544
657
|
|
545
658
|
// Flatten `extends`.
|
546
659
|
for (const extendName of extendList.filter(Boolean)) {
|
@@ -569,6 +682,7 @@ class ConfigArrayFactory {
|
|
569
682
|
criteria: null,
|
570
683
|
env,
|
571
684
|
globals,
|
685
|
+
ignorePattern,
|
572
686
|
noInlineConfig,
|
573
687
|
parser,
|
574
688
|
parserOptions,
|
@@ -40,8 +40,8 @@ const getGlobParent = require("glob-parent");
|
|
40
40
|
const isGlob = require("is-glob");
|
41
41
|
const { escapeRegExp } = require("lodash");
|
42
42
|
const { Minimatch } = require("minimatch");
|
43
|
+
const { IgnorePattern } = require("./config-array");
|
43
44
|
const { CascadingConfigArrayFactory } = require("./cascading-config-array-factory");
|
44
|
-
const { IgnoredPaths } = require("./ignored-paths");
|
45
45
|
const debug = require("debug")("eslint:file-enumerator");
|
46
46
|
|
47
47
|
//------------------------------------------------------------------------------
|
@@ -64,7 +64,6 @@ const IGNORED = 2;
|
|
64
64
|
* @property {string[]} [extensions] The extensions to match files for directory patterns.
|
65
65
|
* @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
|
66
66
|
* @property {boolean} [ignore] The flag to check ignored files.
|
67
|
-
* @property {IgnoredPaths} [ignoredPaths] The ignored paths.
|
68
67
|
* @property {string[]} [rulePaths] The value of `--rulesdir` option.
|
69
68
|
*/
|
70
69
|
|
@@ -92,8 +91,7 @@ const IGNORED = 2;
|
|
92
91
|
* @property {RegExp} extensionRegExp The RegExp to test if a string ends with specific file extensions.
|
93
92
|
* @property {boolean} globInputPaths Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
|
94
93
|
* @property {boolean} ignoreFlag The flag to check ignored files.
|
95
|
-
* @property {
|
96
|
-
* @property {IgnoredPaths} ignoredPaths The ignored paths.
|
94
|
+
* @property {(filePath:string, dot:boolean) => boolean} defaultIgnores The default predicate function to ignore files.
|
97
95
|
*/
|
98
96
|
|
99
97
|
/** @type {WeakMap<FileEnumerator, FileEnumeratorInternalSlots>} */
|
@@ -192,12 +190,13 @@ class FileEnumerator {
|
|
192
190
|
configArrayFactory = new CascadingConfigArrayFactory({ cwd }),
|
193
191
|
extensions = [".js"],
|
194
192
|
globInputPaths = true,
|
195
|
-
|
196
|
-
|
193
|
+
errorOnUnmatchedPattern = true,
|
194
|
+
ignore = true
|
197
195
|
} = {}) {
|
198
196
|
internalSlotsMap.set(this, {
|
199
197
|
configArrayFactory,
|
200
198
|
cwd,
|
199
|
+
defaultIgnores: IgnorePattern.createDefaultIgnore(cwd),
|
201
200
|
extensionRegExp: new RegExp(
|
202
201
|
`.\\.(?:${extensions
|
203
202
|
.map(ext => escapeRegExp(
|
@@ -210,12 +209,8 @@ class FileEnumerator {
|
|
210
209
|
"u"
|
211
210
|
),
|
212
211
|
globInputPaths,
|
213
|
-
|
214
|
-
|
215
|
-
ignoredPathsWithDotfiles: new IgnoredPaths({
|
216
|
-
...ignoredPaths.options,
|
217
|
-
dotfiles: true
|
218
|
-
})
|
212
|
+
errorOnUnmatchedPattern,
|
213
|
+
ignoreFlag: ignore
|
219
214
|
});
|
220
215
|
}
|
221
216
|
|
@@ -233,7 +228,7 @@ class FileEnumerator {
|
|
233
228
|
* @returns {IterableIterator<FileAndConfig>} The found files.
|
234
229
|
*/
|
235
230
|
*iterateFiles(patternOrPatterns) {
|
236
|
-
const { globInputPaths } = internalSlotsMap.get(this);
|
231
|
+
const { globInputPaths, errorOnUnmatchedPattern } = internalSlotsMap.get(this);
|
237
232
|
const patterns = Array.isArray(patternOrPatterns)
|
238
233
|
? patternOrPatterns
|
239
234
|
: [patternOrPatterns];
|
@@ -272,14 +267,16 @@ class FileEnumerator {
|
|
272
267
|
}
|
273
268
|
|
274
269
|
// Raise an error if any files were not found.
|
275
|
-
if (
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
270
|
+
if (errorOnUnmatchedPattern) {
|
271
|
+
if (!foundRegardlessOfIgnored) {
|
272
|
+
throw new NoFilesFoundError(
|
273
|
+
pattern,
|
274
|
+
!globInputPaths && isGlob(pattern)
|
275
|
+
);
|
276
|
+
}
|
277
|
+
if (!found) {
|
278
|
+
throw new AllFilesIgnoredError(pattern);
|
279
|
+
}
|
283
280
|
}
|
284
281
|
}
|
285
282
|
|
@@ -321,7 +318,7 @@ class FileEnumerator {
|
|
321
318
|
|
322
319
|
const { configArrayFactory } = internalSlotsMap.get(this);
|
323
320
|
const config = configArrayFactory.getConfigArrayForFile(filePath);
|
324
|
-
const ignored = this._isIgnoredFile(filePath, { direct: true });
|
321
|
+
const ignored = this._isIgnoredFile(filePath, { config, direct: true });
|
325
322
|
const flag = ignored ? IGNORED : NONE;
|
326
323
|
|
327
324
|
return [{ config, filePath, flag }];
|
@@ -353,7 +350,7 @@ class FileEnumerator {
|
|
353
350
|
_iterateFilesWithGlob(pattern, dotfiles) {
|
354
351
|
debug(`Glob: ${pattern}`);
|
355
352
|
|
356
|
-
const directoryPath = getGlobParent(pattern);
|
353
|
+
const directoryPath = path.resolve(getGlobParent(pattern));
|
357
354
|
const globPart = pattern.slice(directoryPath.length + 1);
|
358
355
|
|
359
356
|
/*
|
@@ -382,9 +379,6 @@ class FileEnumerator {
|
|
382
379
|
* @private
|
383
380
|
*/
|
384
381
|
*_iterateFilesRecursive(directoryPath, options) {
|
385
|
-
if (this._isIgnoredFile(directoryPath + path.sep, options)) {
|
386
|
-
return;
|
387
|
-
}
|
388
382
|
debug(`Enter the directory: ${directoryPath}`);
|
389
383
|
const { configArrayFactory, extensionRegExp } = internalSlotsMap.get(this);
|
390
384
|
|
@@ -399,9 +393,18 @@ class FileEnumerator {
|
|
399
393
|
// Check if the file is matched.
|
400
394
|
if (stat && stat.isFile()) {
|
401
395
|
if (!config) {
|
402
|
-
config = configArrayFactory.getConfigArrayForFile(
|
396
|
+
config = configArrayFactory.getConfigArrayForFile(
|
397
|
+
filePath,
|
398
|
+
|
399
|
+
/*
|
400
|
+
* We must ignore `ConfigurationNotFoundError` at this
|
401
|
+
* point because we don't know if target files exist in
|
402
|
+
* this directory.
|
403
|
+
*/
|
404
|
+
{ ignoreNotFoundError: true }
|
405
|
+
);
|
403
406
|
}
|
404
|
-
const ignored = this._isIgnoredFile(filePath, options);
|
407
|
+
const ignored = this._isIgnoredFile(filePath, { ...options, config });
|
405
408
|
const flag = ignored ? IGNORED_SILENTLY : NONE;
|
406
409
|
const matched = options.selector
|
407
410
|
|
@@ -413,14 +416,31 @@ class FileEnumerator {
|
|
413
416
|
|
414
417
|
if (matched) {
|
415
418
|
debug(`Yield: ${filename}${ignored ? " but ignored" : ""}`);
|
416
|
-
yield {
|
419
|
+
yield {
|
420
|
+
config: configArrayFactory.getConfigArrayForFile(filePath),
|
421
|
+
filePath,
|
422
|
+
flag
|
423
|
+
};
|
417
424
|
} else {
|
418
425
|
debug(`Didn't match: ${filename}`);
|
419
426
|
}
|
420
427
|
|
421
428
|
// Dive into the sub directory.
|
422
429
|
} else if (options.recursive && stat && stat.isDirectory()) {
|
423
|
-
|
430
|
+
if (!config) {
|
431
|
+
config = configArrayFactory.getConfigArrayForFile(
|
432
|
+
filePath,
|
433
|
+
{ ignoreNotFoundError: true }
|
434
|
+
);
|
435
|
+
}
|
436
|
+
const ignored = this._isIgnoredFile(
|
437
|
+
filePath + path.sep,
|
438
|
+
{ ...options, config }
|
439
|
+
);
|
440
|
+
|
441
|
+
if (!ignored) {
|
442
|
+
yield* this._iterateFilesRecursive(filePath, options);
|
443
|
+
}
|
424
444
|
}
|
425
445
|
}
|
426
446
|
|
@@ -431,24 +451,37 @@ class FileEnumerator {
|
|
431
451
|
* Check if a given file should be ignored.
|
432
452
|
* @param {string} filePath The path to a file to check.
|
433
453
|
* @param {Object} options Options
|
454
|
+
* @param {ConfigArray} [options.config] The config for this file.
|
434
455
|
* @param {boolean} [options.dotfiles] If `true` then this is not ignore dot files by default.
|
435
456
|
* @param {boolean} [options.direct] If `true` then this is a direct specified file.
|
436
457
|
* @returns {boolean} `true` if the file should be ignored.
|
437
458
|
* @private
|
438
459
|
*/
|
439
|
-
_isIgnoredFile(filePath, {
|
460
|
+
_isIgnoredFile(filePath, {
|
461
|
+
config: providedConfig,
|
462
|
+
dotfiles = false,
|
463
|
+
direct = false
|
464
|
+
}) {
|
440
465
|
const {
|
441
|
-
|
442
|
-
|
443
|
-
|
466
|
+
configArrayFactory,
|
467
|
+
defaultIgnores,
|
468
|
+
ignoreFlag
|
444
469
|
} = internalSlotsMap.get(this);
|
445
|
-
const adoptedIgnoredPaths = dotfiles
|
446
|
-
? ignoredPathsWithDotfiles
|
447
|
-
: ignoredPaths;
|
448
470
|
|
449
|
-
|
450
|
-
|
451
|
-
|
471
|
+
if (ignoreFlag) {
|
472
|
+
const config =
|
473
|
+
providedConfig ||
|
474
|
+
configArrayFactory.getConfigArrayForFile(
|
475
|
+
filePath,
|
476
|
+
{ ignoreNotFoundError: true }
|
477
|
+
);
|
478
|
+
const ignores =
|
479
|
+
config.extractConfig(filePath).ignores || defaultIgnores;
|
480
|
+
|
481
|
+
return ignores(filePath, dotfiles);
|
482
|
+
}
|
483
|
+
|
484
|
+
return !direct && defaultIgnores(filePath, dotfiles);
|
452
485
|
}
|
453
486
|
}
|
454
487
|
|
@@ -20,6 +20,7 @@ const hash = require("./hash");
|
|
20
20
|
//-----------------------------------------------------------------------------
|
21
21
|
|
22
22
|
const configHashCache = new WeakMap();
|
23
|
+
const nodeVersion = process && process.version;
|
23
24
|
|
24
25
|
/**
|
25
26
|
* Calculates the hash of the config
|
@@ -28,7 +29,7 @@ const configHashCache = new WeakMap();
|
|
28
29
|
*/
|
29
30
|
function hashOfConfigFor(config) {
|
30
31
|
if (!configHashCache.has(config)) {
|
31
|
-
configHashCache.set(config, hash(`${pkg.version}_${stringify(config)}`));
|
32
|
+
configHashCache.set(config, hash(`${pkg.version}_${nodeVersion}_${stringify(config)}`));
|
32
33
|
}
|
33
34
|
|
34
35
|
return configHashCache.get(config);
|
package/lib/cli.js
CHANGED
@@ -68,7 +68,8 @@ function translateOptions(cliOptions) {
|
|
68
68
|
fixTypes: cliOptions.fixType,
|
69
69
|
allowInlineConfig: cliOptions.inlineConfig,
|
70
70
|
reportUnusedDisableDirectives: cliOptions.reportUnusedDisableDirectives,
|
71
|
-
resolvePluginsRelativeTo: cliOptions.resolvePluginsRelativeTo
|
71
|
+
resolvePluginsRelativeTo: cliOptions.resolvePluginsRelativeTo,
|
72
|
+
errorOnUnmatchedPattern: cliOptions.errorOnUnmatchedPattern
|
72
73
|
};
|
73
74
|
}
|
74
75
|
|