eslint 6.5.1 → 6.7.2
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 +118 -0
- package/README.md +10 -9
- package/conf/config-schema.js +1 -0
- package/conf/default-cli-options.js +1 -1
- package/lib/cli-engine/cascading-config-array-factory.js +40 -14
- package/lib/cli-engine/cli-engine.js +49 -21
- package/lib/cli-engine/config-array/config-array.js +13 -4
- package/lib/cli-engine/config-array/config-dependency.js +2 -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/override-tester.js +2 -0
- package/lib/cli-engine/config-array-factory.js +120 -2
- package/lib/cli-engine/file-enumerator.js +65 -34
- package/lib/cli-engine/formatters/html.js +1 -0
- package/lib/init/autoconfig.js +1 -11
- package/lib/init/config-file.js +0 -1
- package/lib/init/config-initializer.js +4 -4
- package/lib/init/config-rule.js +1 -5
- package/lib/init/npm-utils.js +0 -5
- package/lib/linter/code-path-analysis/code-path-analyzer.js +24 -38
- package/lib/linter/code-path-analysis/code-path-segment.js +17 -25
- package/lib/linter/code-path-analysis/code-path-state.js +40 -81
- package/lib/linter/code-path-analysis/code-path.js +10 -11
- package/lib/linter/code-path-analysis/debug-helpers.js +8 -12
- package/lib/linter/code-path-analysis/fork-context.js +23 -34
- package/lib/linter/code-path-analysis/id-generator.js +2 -2
- package/lib/linter/linter.js +121 -95
- package/lib/linter/node-event-generator.js +3 -2
- package/lib/linter/report-translator.js +73 -7
- package/lib/rule-tester/rule-tester.js +46 -14
- package/lib/rules/accessor-pairs.js +8 -8
- package/lib/rules/array-bracket-newline.js +12 -15
- package/lib/rules/array-bracket-spacing.js +12 -12
- package/lib/rules/array-callback-return.js +6 -11
- package/lib/rules/array-element-newline.js +5 -8
- package/lib/rules/arrow-parens.js +0 -1
- package/lib/rules/block-scoped-var.js +3 -3
- package/lib/rules/block-spacing.js +4 -4
- package/lib/rules/camelcase.js +19 -6
- package/lib/rules/capitalized-comments.js +0 -7
- package/lib/rules/class-methods-use-this.js +3 -3
- package/lib/rules/comma-dangle.js +20 -25
- package/lib/rules/comma-spacing.js +1 -1
- package/lib/rules/computed-property-spacing.js +14 -14
- package/lib/rules/consistent-return.js +4 -5
- package/lib/rules/consistent-this.js +5 -5
- package/lib/rules/constructor-super.js +14 -16
- package/lib/rules/curly.js +12 -9
- package/lib/rules/default-param-last.js +1 -0
- package/lib/rules/dot-location.js +11 -12
- package/lib/rules/func-names.js +6 -6
- package/lib/rules/function-call-argument-newline.js +8 -6
- package/lib/rules/generator-star-spacing.js +4 -9
- package/lib/rules/getter-return.js +4 -7
- package/lib/rules/grouped-accessor-pairs.js +224 -0
- package/lib/rules/indent.js +13 -2
- package/lib/rules/index.js +5 -0
- package/lib/rules/init-declarations.js +2 -2
- package/lib/rules/jsx-quotes.js +1 -1
- package/lib/rules/keyword-spacing.js +32 -56
- package/lib/rules/lines-around-directive.js +1 -1
- package/lib/rules/max-len.js +0 -5
- package/lib/rules/max-statements-per-line.js +3 -7
- package/lib/rules/multiline-comment-style.js +237 -106
- package/lib/rules/multiline-ternary.js +3 -3
- package/lib/rules/newline-after-var.js +6 -7
- package/lib/rules/newline-before-return.js +8 -9
- package/lib/rules/newline-per-chained-call.js +2 -4
- package/lib/rules/no-class-assign.js +2 -2
- package/lib/rules/no-compare-neg-zero.js +1 -2
- package/lib/rules/no-cond-assign.js +14 -4
- package/lib/rules/no-confusing-arrow.js +2 -2
- package/lib/rules/no-console.js +4 -8
- package/lib/rules/no-const-assign.js +1 -1
- package/lib/rules/no-constructor-return.js +62 -0
- package/lib/rules/no-dupe-args.js +1 -1
- package/lib/rules/no-dupe-class-members.js +3 -4
- package/lib/rules/no-dupe-else-if.js +122 -0
- package/lib/rules/no-dupe-keys.js +6 -5
- package/lib/rules/no-duplicate-imports.js +14 -18
- package/lib/rules/no-else-return.js +0 -8
- package/lib/rules/no-empty-function.js +2 -4
- package/lib/rules/no-eval.js +10 -18
- package/lib/rules/no-ex-assign.js +1 -1
- package/lib/rules/no-extra-bind.js +5 -12
- package/lib/rules/no-extra-boolean-cast.js +0 -2
- package/lib/rules/no-extra-label.js +4 -9
- package/lib/rules/no-extra-parens.js +17 -15
- package/lib/rules/no-extra-semi.js +5 -6
- package/lib/rules/no-fallthrough.js +6 -6
- package/lib/rules/no-func-assign.js +3 -3
- package/lib/rules/no-global-assign.js +4 -4
- package/lib/rules/no-implicit-coercion.js +10 -10
- package/lib/rules/no-implicit-globals.js +90 -8
- package/lib/rules/no-implied-eval.js +0 -1
- package/lib/rules/no-inline-comments.js +25 -11
- package/lib/rules/no-invalid-this.js +17 -5
- package/lib/rules/no-labels.js +3 -6
- package/lib/rules/no-lone-blocks.js +1 -1
- package/lib/rules/no-loop-func.js +6 -11
- package/lib/rules/no-magic-numbers.js +6 -6
- package/lib/rules/no-misleading-character-class.js +14 -7
- package/lib/rules/no-mixed-operators.js +13 -22
- package/lib/rules/no-mixed-requires.js +0 -1
- package/lib/rules/no-multi-spaces.js +1 -1
- package/lib/rules/no-native-reassign.js +4 -4
- package/lib/rules/no-octal-escape.js +1 -1
- package/lib/rules/no-param-reassign.js +28 -7
- package/lib/rules/no-redeclare.js +1 -1
- package/lib/rules/no-regex-spaces.js +0 -1
- package/lib/rules/no-restricted-imports.js +11 -11
- package/lib/rules/no-self-assign.js +12 -13
- package/lib/rules/no-sequences.js +3 -3
- package/lib/rules/no-setter-return.js +227 -0
- package/lib/rules/no-shadow.js +1 -4
- package/lib/rules/no-tabs.js +8 -2
- package/lib/rules/no-this-before-super.js +12 -13
- package/lib/rules/no-trailing-spaces.js +19 -7
- package/lib/rules/no-underscore-dangle.js +23 -4
- package/lib/rules/no-unexpected-multiline.js +8 -0
- package/lib/rules/no-unmodified-loop-condition.js +16 -29
- package/lib/rules/no-unneeded-ternary.js +3 -3
- package/lib/rules/no-unreachable.js +7 -7
- package/lib/rules/no-unsafe-finally.js +4 -7
- package/lib/rules/no-unsafe-negation.js +32 -9
- package/lib/rules/no-unused-expressions.js +11 -7
- package/lib/rules/no-unused-labels.js +3 -6
- package/lib/rules/no-unused-vars.js +22 -29
- package/lib/rules/no-use-before-define.js +10 -15
- package/lib/rules/no-useless-call.js +4 -4
- package/lib/rules/no-useless-computed-key.js +60 -33
- package/lib/rules/no-useless-concat.js +4 -4
- package/lib/rules/no-useless-constructor.js +14 -22
- package/lib/rules/no-useless-escape.js +29 -8
- package/lib/rules/no-useless-rename.js +7 -7
- package/lib/rules/no-useless-return.js +8 -15
- package/lib/rules/no-var.js +12 -25
- package/lib/rules/no-warning-comments.js +0 -1
- package/lib/rules/no-whitespace-before-property.js +3 -3
- package/lib/rules/object-curly-newline.js +7 -10
- package/lib/rules/object-curly-spacing.js +21 -22
- package/lib/rules/object-shorthand.js +1 -1
- package/lib/rules/one-var-declaration-per-line.js +2 -2
- package/lib/rules/operator-assignment.js +33 -3
- package/lib/rules/padded-blocks.js +1 -1
- package/lib/rules/padding-line-between-statements.js +0 -16
- package/lib/rules/prefer-arrow-callback.js +6 -6
- package/lib/rules/prefer-const.js +27 -28
- package/lib/rules/prefer-destructuring.js +1 -7
- package/lib/rules/prefer-exponentiation-operator.js +189 -0
- package/lib/rules/prefer-named-capture-group.js +0 -1
- package/lib/rules/prefer-numeric-literals.js +32 -4
- package/lib/rules/prefer-object-spread.js +7 -7
- package/lib/rules/prefer-rest-params.js +3 -6
- package/lib/rules/prefer-spread.js +4 -4
- package/lib/rules/prefer-template.js +5 -6
- package/lib/rules/quote-props.js +1 -1
- package/lib/rules/quotes.js +5 -6
- package/lib/rules/radix.js +5 -10
- package/lib/rules/require-await.js +10 -5
- package/lib/rules/require-yield.js +2 -2
- package/lib/rules/rest-spread-spacing.js +1 -1
- package/lib/rules/semi.js +6 -3
- package/lib/rules/sort-imports.js +3 -4
- package/lib/rules/sort-keys.js +1 -3
- package/lib/rules/space-before-blocks.js +1 -2
- package/lib/rules/space-in-parens.js +4 -4
- package/lib/rules/space-infix-ops.js +6 -6
- package/lib/rules/spaced-comment.js +20 -22
- package/lib/rules/strict.js +2 -4
- package/lib/rules/symbol-description.js +1 -2
- package/lib/rules/template-curly-spacing.js +2 -2
- package/lib/rules/use-isnan.js +40 -3
- package/lib/rules/utils/ast-utils.js +84 -85
- package/lib/rules/utils/fix-tracker.js +0 -6
- package/lib/rules/utils/lazy-loading-rule-map.js +0 -1
- package/lib/rules/vars-on-top.js +11 -11
- package/lib/shared/config-ops.js +2 -2
- package/lib/shared/runtime-info.js +8 -8
- package/lib/shared/traverser.js +2 -0
- package/lib/shared/types.js +9 -0
- package/lib/source-code/source-code.js +94 -17
- package/lib/source-code/token-store/backward-token-comment-cursor.js +5 -5
- package/lib/source-code/token-store/backward-token-cursor.js +5 -5
- package/lib/source-code/token-store/cursors.js +17 -19
- package/lib/source-code/token-store/decorative-cursor.js +1 -1
- package/lib/source-code/token-store/filter-cursor.js +2 -2
- package/lib/source-code/token-store/forward-token-comment-cursor.js +5 -5
- package/lib/source-code/token-store/forward-token-cursor.js +5 -5
- package/lib/source-code/token-store/index.js +86 -92
- package/lib/source-code/token-store/limit-cursor.js +2 -2
- package/lib/source-code/token-store/padded-token-cursor.js +7 -7
- package/lib/source-code/token-store/skip-cursor.js +2 -2
- package/lib/source-code/token-store/utils.js +9 -13
- package/package.json +9 -7
- package/lib/cli-engine/ignored-paths.js +0 -362
@@ -31,6 +31,7 @@
|
|
31
31
|
//------------------------------------------------------------------------------
|
32
32
|
|
33
33
|
const { ExtractedConfig } = require("./extracted-config");
|
34
|
+
const { IgnorePattern } = require("./ignore-pattern");
|
34
35
|
|
35
36
|
//------------------------------------------------------------------------------
|
36
37
|
// Helpers
|
@@ -54,6 +55,7 @@ const { ExtractedConfig } = require("./extracted-config");
|
|
54
55
|
* @property {InstanceType<OverrideTester>|null} criteria The tester for the `files` and `excludedFiles` of this config element.
|
55
56
|
* @property {Record<string, boolean>|undefined} env The environment settings.
|
56
57
|
* @property {Record<string, GlobalConf>|undefined} globals The global variable settings.
|
58
|
+
* @property {IgnorePattern|undefined} ignorePattern The ignore patterns.
|
57
59
|
* @property {boolean|undefined} noInlineConfig The flag that disables directive comments.
|
58
60
|
* @property {DependentParser|undefined} parser The parser loader.
|
59
61
|
* @property {Object|undefined} parserOptions The parser options.
|
@@ -126,7 +128,6 @@ function isNonNullObject(x) {
|
|
126
128
|
*
|
127
129
|
* Assign every property values of `y` to `x` if `x` doesn't have the property.
|
128
130
|
* If `x`'s property value is an object, it does recursive.
|
129
|
-
*
|
130
131
|
* @param {Object} target The destination to merge
|
131
132
|
* @param {Object|undefined} source The source to merge.
|
132
133
|
* @returns {void}
|
@@ -157,7 +158,6 @@ function mergeWithoutOverwrite(target, source) {
|
|
157
158
|
/**
|
158
159
|
* Merge plugins.
|
159
160
|
* `target`'s definition is prior to `source`'s.
|
160
|
-
*
|
161
161
|
* @param {Record<string, DependentPlugin>} target The destination to merge
|
162
162
|
* @param {Record<string, DependentPlugin>|undefined} source The source to merge.
|
163
163
|
* @returns {void}
|
@@ -187,7 +187,6 @@ function mergePlugins(target, source) {
|
|
187
187
|
/**
|
188
188
|
* Merge rule configs.
|
189
189
|
* `target`'s definition is prior to `source`'s.
|
190
|
-
*
|
191
190
|
* @param {Record<string, Array>} target The destination to merge
|
192
191
|
* @param {Record<string, RuleConf>|undefined} source The source to merge.
|
193
192
|
* @returns {void}
|
@@ -234,6 +233,7 @@ function mergeRuleConfigs(target, source) {
|
|
234
233
|
*/
|
235
234
|
function createConfig(instance, indices) {
|
236
235
|
const config = new ExtractedConfig();
|
236
|
+
const ignorePatterns = [];
|
237
237
|
|
238
238
|
// Merge elements.
|
239
239
|
for (const index of indices) {
|
@@ -263,6 +263,11 @@ function createConfig(instance, indices) {
|
|
263
263
|
config.reportUnusedDisableDirectives = element.reportUnusedDisableDirectives;
|
264
264
|
}
|
265
265
|
|
266
|
+
// Collect ignorePatterns
|
267
|
+
if (element.ignorePattern) {
|
268
|
+
ignorePatterns.push(element.ignorePattern);
|
269
|
+
}
|
270
|
+
|
266
271
|
// Merge others.
|
267
272
|
mergeWithoutOverwrite(config.env, element.env);
|
268
273
|
mergeWithoutOverwrite(config.globals, element.globals);
|
@@ -272,6 +277,11 @@ function createConfig(instance, indices) {
|
|
272
277
|
mergeRuleConfigs(config.rules, element.rules);
|
273
278
|
}
|
274
279
|
|
280
|
+
// Create the predicate function for ignore patterns.
|
281
|
+
if (ignorePatterns.length > 0) {
|
282
|
+
config.ignores = IgnorePattern.createIgnore(ignorePatterns.reverse());
|
283
|
+
}
|
284
|
+
|
275
285
|
return config;
|
276
286
|
}
|
277
287
|
|
@@ -382,7 +392,6 @@ function ensurePluginMemberMaps(instance) {
|
|
382
392
|
* You need to call `ConfigArray#extractConfig(filePath)` method in order to
|
383
393
|
* extract, merge and get only the config data which is related to an arbitrary
|
384
394
|
* file.
|
385
|
-
*
|
386
395
|
* @extends {Array<ConfigArrayElement>}
|
387
396
|
*/
|
388
397
|
class ConfigArray extends Array {
|
@@ -81,6 +81,7 @@ class ConfigDependency {
|
|
81
81
|
this.importerPath = importerPath;
|
82
82
|
}
|
83
83
|
|
84
|
+
// eslint-disable-next-line jsdoc/require-description
|
84
85
|
/**
|
85
86
|
* @returns {Object} a JSON compatible object.
|
86
87
|
*/
|
@@ -95,6 +96,7 @@ class ConfigDependency {
|
|
95
96
|
return obj;
|
96
97
|
}
|
97
98
|
|
99
|
+
// eslint-disable-next-line jsdoc/require-description
|
98
100
|
/**
|
99
101
|
* @returns {Object} an object to display by `console.log()`.
|
100
102
|
*/
|
@@ -16,6 +16,8 @@
|
|
16
16
|
*/
|
17
17
|
"use strict";
|
18
18
|
|
19
|
+
const { IgnorePattern } = require("./ignore-pattern");
|
20
|
+
|
19
21
|
// For VSCode intellisense
|
20
22
|
/** @typedef {import("../../shared/types").ConfigData} ConfigData */
|
21
23
|
/** @typedef {import("../../shared/types").GlobalConf} GlobalConf */
|
@@ -23,6 +25,17 @@
|
|
23
25
|
/** @typedef {import("./config-dependency").DependentParser} DependentParser */
|
24
26
|
/** @typedef {import("./config-dependency").DependentPlugin} DependentPlugin */
|
25
27
|
|
28
|
+
/**
|
29
|
+
* Check if `xs` starts with `ys`.
|
30
|
+
* @template T
|
31
|
+
* @param {T[]} xs The array to check.
|
32
|
+
* @param {T[]} ys The array that may be the first part of `xs`.
|
33
|
+
* @returns {boolean} `true` if `xs` starts with `ys`.
|
34
|
+
*/
|
35
|
+
function startsWith(xs, ys) {
|
36
|
+
return xs.length >= ys.length && ys.every((y, i) => y === xs[i]);
|
37
|
+
}
|
38
|
+
|
26
39
|
/**
|
27
40
|
* The class for extracted config data.
|
28
41
|
*/
|
@@ -47,6 +60,12 @@ class ExtractedConfig {
|
|
47
60
|
*/
|
48
61
|
this.globals = {};
|
49
62
|
|
63
|
+
/**
|
64
|
+
* The glob patterns that ignore to lint.
|
65
|
+
* @type {(((filePath:string, dot?:boolean) => boolean) & { basePath:string; patterns:string[] }) | undefined}
|
66
|
+
*/
|
67
|
+
this.ignores = void 0;
|
68
|
+
|
50
69
|
/**
|
51
70
|
* The flag that disables directive comments.
|
52
71
|
* @type {boolean|undefined}
|
@@ -106,11 +125,19 @@ class ExtractedConfig {
|
|
106
125
|
configNameOfNoInlineConfig: _ignore1,
|
107
126
|
processor: _ignore2,
|
108
127
|
/* eslint-enable no-unused-vars */
|
128
|
+
ignores,
|
109
129
|
...config
|
110
130
|
} = this;
|
111
131
|
|
112
132
|
config.parser = config.parser && config.parser.filePath;
|
113
133
|
config.plugins = Object.keys(config.plugins).filter(Boolean).reverse();
|
134
|
+
config.ignorePatterns = ignores ? ignores.patterns : [];
|
135
|
+
|
136
|
+
// Strip the default patterns from `ignorePatterns`.
|
137
|
+
if (startsWith(config.ignorePatterns, IgnorePattern.DefaultPatterns)) {
|
138
|
+
config.ignorePatterns =
|
139
|
+
config.ignorePatterns.slice(IgnorePattern.DefaultPatterns.length);
|
140
|
+
}
|
114
141
|
|
115
142
|
return config;
|
116
143
|
}
|
@@ -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
|
};
|
@@ -166,6 +166,7 @@ class OverrideTester {
|
|
166
166
|
));
|
167
167
|
}
|
168
168
|
|
169
|
+
// eslint-disable-next-line jsdoc/require-description
|
169
170
|
/**
|
170
171
|
* @returns {Object} a JSON compatible object.
|
171
172
|
*/
|
@@ -182,6 +183,7 @@ class OverrideTester {
|
|
182
183
|
};
|
183
184
|
}
|
184
185
|
|
186
|
+
// eslint-disable-next-line jsdoc/require-description
|
185
187
|
/**
|
186
188
|
* @returns {Object} an object to display by `console.log()`.
|
187
189
|
*/
|
@@ -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
|
//------------------------------------------------------------------------------
|
@@ -221,6 +232,26 @@ function loadPackageJSONConfigFile(filePath) {
|
|
221
232
|
}
|
222
233
|
}
|
223
234
|
|
235
|
+
/**
|
236
|
+
* Loads a `.eslintignore` from a file.
|
237
|
+
* @param {string} filePath The filename to load.
|
238
|
+
* @returns {string[]} The ignore patterns from the file.
|
239
|
+
* @private
|
240
|
+
*/
|
241
|
+
function loadESLintIgnoreFile(filePath) {
|
242
|
+
debug(`Loading .eslintignore file: ${filePath}`);
|
243
|
+
|
244
|
+
try {
|
245
|
+
return readFile(filePath)
|
246
|
+
.split(/\r?\n/gu)
|
247
|
+
.filter(line => line.trim() !== "" && !line.startsWith("#"));
|
248
|
+
} catch (e) {
|
249
|
+
debug(`Error reading .eslintignore file: ${filePath}`);
|
250
|
+
e.message = `Cannot read .eslintignore file: ${filePath}\nError: ${e.message}`;
|
251
|
+
throw e;
|
252
|
+
}
|
253
|
+
}
|
254
|
+
|
224
255
|
/**
|
225
256
|
* Creates an error to notify about a missing config to extend from.
|
226
257
|
* @param {string} configName The name of the missing config.
|
@@ -403,6 +434,54 @@ class ConfigArrayFactory {
|
|
403
434
|
);
|
404
435
|
}
|
405
436
|
|
437
|
+
/**
|
438
|
+
* Load `.eslintignore` file.
|
439
|
+
* @param {string} filePath The path to a `.eslintignore` file to load.
|
440
|
+
* @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist.
|
441
|
+
*/
|
442
|
+
loadESLintIgnore(filePath) {
|
443
|
+
const { cwd } = internalSlotsMap.get(this);
|
444
|
+
const absolutePath = path.resolve(cwd, filePath);
|
445
|
+
const name = path.relative(cwd, absolutePath);
|
446
|
+
const ignorePatterns = loadESLintIgnoreFile(absolutePath);
|
447
|
+
|
448
|
+
return createConfigArray(
|
449
|
+
this._normalizeESLintIgnoreData(ignorePatterns, absolutePath, name)
|
450
|
+
);
|
451
|
+
}
|
452
|
+
|
453
|
+
/**
|
454
|
+
* Load `.eslintignore` file in the current working directory.
|
455
|
+
* @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist.
|
456
|
+
*/
|
457
|
+
loadDefaultESLintIgnore() {
|
458
|
+
const { cwd } = internalSlotsMap.get(this);
|
459
|
+
const eslintIgnorePath = path.resolve(cwd, ".eslintignore");
|
460
|
+
const packageJsonPath = path.resolve(cwd, "package.json");
|
461
|
+
|
462
|
+
if (fs.existsSync(eslintIgnorePath)) {
|
463
|
+
return this.loadESLintIgnore(eslintIgnorePath);
|
464
|
+
}
|
465
|
+
if (fs.existsSync(packageJsonPath)) {
|
466
|
+
const data = loadJSONConfigFile(packageJsonPath);
|
467
|
+
|
468
|
+
if (Object.hasOwnProperty.call(data, "eslintIgnore")) {
|
469
|
+
if (!Array.isArray(data.eslintIgnore)) {
|
470
|
+
throw new Error("Package.json eslintIgnore property requires an array of paths");
|
471
|
+
}
|
472
|
+
return createConfigArray(
|
473
|
+
this._normalizeESLintIgnoreData(
|
474
|
+
data.eslintIgnore,
|
475
|
+
packageJsonPath,
|
476
|
+
"eslintIgnore in package.json"
|
477
|
+
)
|
478
|
+
);
|
479
|
+
}
|
480
|
+
}
|
481
|
+
|
482
|
+
return new ConfigArray();
|
483
|
+
}
|
484
|
+
|
406
485
|
/**
|
407
486
|
* Load a given config file.
|
408
487
|
* @param {string} filePath The path to a config file.
|
@@ -451,6 +530,30 @@ class ConfigArrayFactory {
|
|
451
530
|
return null;
|
452
531
|
}
|
453
532
|
|
533
|
+
/**
|
534
|
+
* Normalize a given `.eslintignore` data to config array elements.
|
535
|
+
* @param {string[]} ignorePatterns The patterns to ignore files.
|
536
|
+
* @param {string|undefined} filePath The file path of this config.
|
537
|
+
* @param {string|undefined} name The name of this config.
|
538
|
+
* @returns {IterableIterator<ConfigArrayElement>} The normalized config.
|
539
|
+
* @private
|
540
|
+
*/
|
541
|
+
*_normalizeESLintIgnoreData(ignorePatterns, filePath, name) {
|
542
|
+
const elements = this._normalizeObjectConfigData(
|
543
|
+
{ ignorePatterns },
|
544
|
+
filePath,
|
545
|
+
name
|
546
|
+
);
|
547
|
+
|
548
|
+
// Set `ignorePattern.loose` flag for backward compatibility.
|
549
|
+
for (const element of elements) {
|
550
|
+
if (element.ignorePattern) {
|
551
|
+
element.ignorePattern.loose = true;
|
552
|
+
}
|
553
|
+
yield element;
|
554
|
+
}
|
555
|
+
}
|
556
|
+
|
454
557
|
/**
|
455
558
|
* Normalize a given config to an array.
|
456
559
|
* @param {ConfigData} configData The config data to normalize.
|
@@ -494,6 +597,9 @@ class ConfigArrayFactory {
|
|
494
597
|
if (element.criteria) {
|
495
598
|
element.criteria.basePath = basePath;
|
496
599
|
}
|
600
|
+
if (element.ignorePattern) {
|
601
|
+
element.ignorePattern.basePath = basePath;
|
602
|
+
}
|
497
603
|
|
498
604
|
/*
|
499
605
|
* Merge the criteria; this is for only file extension processors in
|
@@ -526,6 +632,7 @@ class ConfigArrayFactory {
|
|
526
632
|
env,
|
527
633
|
extends: extend,
|
528
634
|
globals,
|
635
|
+
ignorePatterns,
|
529
636
|
noInlineConfig,
|
530
637
|
parser: parserName,
|
531
638
|
parserOptions,
|
@@ -541,6 +648,10 @@ class ConfigArrayFactory {
|
|
541
648
|
name
|
542
649
|
) {
|
543
650
|
const extendList = Array.isArray(extend) ? extend : [extend];
|
651
|
+
const ignorePattern = ignorePatterns && new IgnorePattern(
|
652
|
+
Array.isArray(ignorePatterns) ? ignorePatterns : [ignorePatterns],
|
653
|
+
filePath ? path.dirname(filePath) : internalSlotsMap.get(this).cwd
|
654
|
+
);
|
544
655
|
|
545
656
|
// Flatten `extends`.
|
546
657
|
for (const extendName of extendList.filter(Boolean)) {
|
@@ -569,6 +680,7 @@ class ConfigArrayFactory {
|
|
569
680
|
criteria: null,
|
570
681
|
env,
|
571
682
|
globals,
|
683
|
+
ignorePattern,
|
572
684
|
noInlineConfig,
|
573
685
|
parser,
|
574
686
|
parserOptions,
|
@@ -859,8 +971,14 @@ class ConfigArrayFactory {
|
|
859
971
|
if (filePath) {
|
860
972
|
try {
|
861
973
|
writeDebugLogForLoading(request, relativeTo, filePath);
|
974
|
+
|
975
|
+
const startTime = Date.now();
|
976
|
+
const pluginDefinition = require(filePath);
|
977
|
+
|
978
|
+
debug(`Plugin ${filePath} loaded in: ${Date.now() - startTime}ms`);
|
979
|
+
|
862
980
|
return new ConfigDependency({
|
863
|
-
definition: normalizePlugin(
|
981
|
+
definition: normalizePlugin(pluginDefinition),
|
864
982
|
filePath,
|
865
983
|
id,
|
866
984
|
importerName,
|