eslint 8.25.0 → 8.27.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/lib/cli-engine/formatters/html.js +76 -51
- package/lib/cli.js +29 -8
- package/lib/config/default-config.js +1 -1
- package/lib/eslint/eslint-helpers.js +397 -94
- package/lib/eslint/flat-eslint.js +56 -45
- package/lib/linter/linter.js +1 -0
- package/lib/rules/comma-dangle.js +2 -2
- package/lib/rules/func-name-matching.js +2 -2
- package/lib/rules/getter-return.js +14 -8
- package/lib/rules/index.js +2 -0
- package/lib/rules/no-empty-static-block.js +47 -0
- package/lib/rules/no-empty.js +19 -2
- package/lib/rules/no-implicit-globals.js +5 -0
- package/lib/rules/no-misleading-character-class.js +4 -4
- package/lib/rules/no-new-native-nonconstructor.js +64 -0
- package/lib/rules/prefer-regex-literals.js +4 -4
- package/package.json +5 -4
@@ -13,9 +13,30 @@ const path = require("path");
|
|
13
13
|
const fs = require("fs");
|
14
14
|
const fsp = fs.promises;
|
15
15
|
const isGlob = require("is-glob");
|
16
|
-
const globby = require("globby");
|
17
16
|
const hash = require("../cli-engine/hash");
|
18
17
|
const minimatch = require("minimatch");
|
18
|
+
const util = require("util");
|
19
|
+
const fswalk = require("@nodelib/fs.walk");
|
20
|
+
const globParent = require("glob-parent");
|
21
|
+
const isPathInside = require("is-path-inside");
|
22
|
+
|
23
|
+
//-----------------------------------------------------------------------------
|
24
|
+
// Fixup references
|
25
|
+
//-----------------------------------------------------------------------------
|
26
|
+
|
27
|
+
const doFsWalk = util.promisify(fswalk.walk);
|
28
|
+
const Minimatch = minimatch.Minimatch;
|
29
|
+
|
30
|
+
//-----------------------------------------------------------------------------
|
31
|
+
// Types
|
32
|
+
//-----------------------------------------------------------------------------
|
33
|
+
|
34
|
+
/**
|
35
|
+
* @typedef {Object} GlobSearch
|
36
|
+
* @property {Array<string>} patterns The normalized patterns to use for a search.
|
37
|
+
* @property {Array<string>} rawPatterns The patterns as entered by the user
|
38
|
+
* before doing any normalization.
|
39
|
+
*/
|
19
40
|
|
20
41
|
//-----------------------------------------------------------------------------
|
21
42
|
// Errors
|
@@ -37,6 +58,30 @@ class NoFilesFoundError extends Error {
|
|
37
58
|
}
|
38
59
|
}
|
39
60
|
|
61
|
+
/**
|
62
|
+
* The error type when a search fails to match multiple patterns.
|
63
|
+
*/
|
64
|
+
class UnmatchedSearchPatternsError extends Error {
|
65
|
+
|
66
|
+
/**
|
67
|
+
* @param {Object} options The options for the error.
|
68
|
+
* @param {string} options.basePath The directory that was searched.
|
69
|
+
* @param {Array<string>} options.unmatchedPatterns The glob patterns
|
70
|
+
* which were not found.
|
71
|
+
* @param {Array<string>} options.patterns The glob patterns that were
|
72
|
+
* searched.
|
73
|
+
* @param {Array<string>} options.rawPatterns The raw glob patterns that
|
74
|
+
* were searched.
|
75
|
+
*/
|
76
|
+
constructor({ basePath, unmatchedPatterns, patterns, rawPatterns }) {
|
77
|
+
super(`No files matching '${rawPatterns}' in '${basePath}' were found.`);
|
78
|
+
this.basePath = basePath;
|
79
|
+
this.patternsToCheck = unmatchedPatterns;
|
80
|
+
this.patterns = patterns;
|
81
|
+
this.rawPatterns = rawPatterns;
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
40
85
|
/**
|
41
86
|
* The error type when there are files matched by a glob, but all of them have been ignored.
|
42
87
|
*/
|
@@ -97,6 +142,323 @@ function isGlobPattern(pattern) {
|
|
97
142
|
return isGlob(path.sep === "\\" ? normalizeToPosix(pattern) : pattern);
|
98
143
|
}
|
99
144
|
|
145
|
+
|
146
|
+
/**
|
147
|
+
* Determines if a given glob pattern will return any results.
|
148
|
+
* Used primarily to help with useful error messages.
|
149
|
+
* @param {Object} options The options for the function.
|
150
|
+
* @param {string} options.basePath The directory to search.
|
151
|
+
* @param {string} options.pattern A glob pattern to match.
|
152
|
+
* @returns {Promise<boolean>} True if there is a glob match, false if not.
|
153
|
+
*/
|
154
|
+
function globMatch({ basePath, pattern }) {
|
155
|
+
|
156
|
+
let found = false;
|
157
|
+
const patternToUse = path.isAbsolute(pattern)
|
158
|
+
? normalizeToPosix(path.relative(basePath, pattern))
|
159
|
+
: pattern;
|
160
|
+
|
161
|
+
const matcher = new Minimatch(patternToUse);
|
162
|
+
|
163
|
+
const fsWalkSettings = {
|
164
|
+
|
165
|
+
deepFilter(entry) {
|
166
|
+
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
167
|
+
|
168
|
+
return !found && matcher.match(relativePath, true);
|
169
|
+
},
|
170
|
+
|
171
|
+
entryFilter(entry) {
|
172
|
+
if (found || entry.dirent.isDirectory()) {
|
173
|
+
return false;
|
174
|
+
}
|
175
|
+
|
176
|
+
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
177
|
+
|
178
|
+
if (matcher.match(relativePath)) {
|
179
|
+
found = true;
|
180
|
+
return true;
|
181
|
+
}
|
182
|
+
|
183
|
+
return false;
|
184
|
+
}
|
185
|
+
};
|
186
|
+
|
187
|
+
return new Promise(resolve => {
|
188
|
+
|
189
|
+
// using a stream so we can exit early because we just need one match
|
190
|
+
const globStream = fswalk.walkStream(basePath, fsWalkSettings);
|
191
|
+
|
192
|
+
globStream.on("data", () => {
|
193
|
+
globStream.destroy();
|
194
|
+
resolve(true);
|
195
|
+
});
|
196
|
+
|
197
|
+
// swallow errors as they're not important here
|
198
|
+
globStream.on("error", () => { });
|
199
|
+
|
200
|
+
globStream.on("end", () => {
|
201
|
+
resolve(false);
|
202
|
+
});
|
203
|
+
globStream.read();
|
204
|
+
});
|
205
|
+
|
206
|
+
}
|
207
|
+
|
208
|
+
/**
|
209
|
+
* Searches a directory looking for matching glob patterns. This uses
|
210
|
+
* the config array's logic to determine if a directory or file should
|
211
|
+
* be ignored, so it is consistent with how ignoring works throughout
|
212
|
+
* ESLint.
|
213
|
+
* @param {Object} options The options for this function.
|
214
|
+
* @param {string} options.basePath The directory to search.
|
215
|
+
* @param {Array<string>} options.patterns An array of glob patterns
|
216
|
+
* to match.
|
217
|
+
* @param {Array<string>} options.rawPatterns An array of glob patterns
|
218
|
+
* as the user inputted them. Used for errors.
|
219
|
+
* @param {FlatConfigArray} options.configs The config array to use for
|
220
|
+
* determining what to ignore.
|
221
|
+
* @param {boolean} options.errorOnUnmatchedPattern Determines if an error
|
222
|
+
* should be thrown when a pattern is unmatched.
|
223
|
+
* @returns {Promise<Array<string>>} An array of matching file paths
|
224
|
+
* or an empty array if there are no matches.
|
225
|
+
* @throws {UnmatchedSearchPatternsErrror} If there is a pattern that doesn't
|
226
|
+
* match any files.
|
227
|
+
*/
|
228
|
+
async function globSearch({
|
229
|
+
basePath,
|
230
|
+
patterns,
|
231
|
+
rawPatterns,
|
232
|
+
configs,
|
233
|
+
errorOnUnmatchedPattern
|
234
|
+
}) {
|
235
|
+
|
236
|
+
if (patterns.length === 0) {
|
237
|
+
return [];
|
238
|
+
}
|
239
|
+
|
240
|
+
/*
|
241
|
+
* In this section we are converting the patterns into Minimatch
|
242
|
+
* instances for performance reasons. Because we are doing the same
|
243
|
+
* matches repeatedly, it's best to compile those patterns once and
|
244
|
+
* reuse them multiple times.
|
245
|
+
*
|
246
|
+
* To do that, we convert any patterns with an absolute path into a
|
247
|
+
* relative path and normalize it to Posix-style slashes. We also keep
|
248
|
+
* track of the relative patterns to map them back to the original
|
249
|
+
* patterns, which we need in order to throw an error if there are any
|
250
|
+
* unmatched patterns.
|
251
|
+
*/
|
252
|
+
const relativeToPatterns = new Map();
|
253
|
+
const matchers = patterns.map((pattern, i) => {
|
254
|
+
const patternToUse = path.isAbsolute(pattern)
|
255
|
+
? normalizeToPosix(path.relative(basePath, pattern))
|
256
|
+
: pattern;
|
257
|
+
|
258
|
+
relativeToPatterns.set(patternToUse, patterns[i]);
|
259
|
+
|
260
|
+
return new minimatch.Minimatch(patternToUse);
|
261
|
+
});
|
262
|
+
|
263
|
+
/*
|
264
|
+
* We track unmatched patterns because we may want to throw an error when
|
265
|
+
* they occur. To start, this set is initialized with all of the patterns.
|
266
|
+
* Every time a match occurs, the pattern is removed from the set, making
|
267
|
+
* it easy to tell if we have any unmatched patterns left at the end of
|
268
|
+
* search.
|
269
|
+
*/
|
270
|
+
const unmatchedPatterns = new Set([...relativeToPatterns.keys()]);
|
271
|
+
|
272
|
+
const filePaths = (await doFsWalk(basePath, {
|
273
|
+
|
274
|
+
deepFilter(entry) {
|
275
|
+
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
276
|
+
const matchesPattern = matchers.some(matcher => matcher.match(relativePath, true));
|
277
|
+
|
278
|
+
return matchesPattern && !configs.isDirectoryIgnored(entry.path);
|
279
|
+
},
|
280
|
+
entryFilter(entry) {
|
281
|
+
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
282
|
+
|
283
|
+
// entries may be directories or files so filter out directories
|
284
|
+
if (entry.dirent.isDirectory()) {
|
285
|
+
return false;
|
286
|
+
}
|
287
|
+
|
288
|
+
/*
|
289
|
+
* Optimization: We need to track when patterns are left unmatched
|
290
|
+
* and so we use `unmatchedPatterns` to do that. There is a bit of
|
291
|
+
* complexity here because the same file can be matched by more than
|
292
|
+
* one pattern. So, when we start, we actually need to test every
|
293
|
+
* pattern against every file. Once we know there are no remaining
|
294
|
+
* unmatched patterns, then we can switch to just looking for the
|
295
|
+
* first matching pattern for improved speed.
|
296
|
+
*/
|
297
|
+
const matchesPattern = unmatchedPatterns.size > 0
|
298
|
+
? matchers.reduce((previousValue, matcher) => {
|
299
|
+
const pathMatches = matcher.match(relativePath);
|
300
|
+
|
301
|
+
/*
|
302
|
+
* We updated the unmatched patterns set only if the path
|
303
|
+
* matches and the file isn't ignored. If the file is
|
304
|
+
* ignored, that means there wasn't a match for the
|
305
|
+
* pattern so it should not be removed.
|
306
|
+
*
|
307
|
+
* Performance note: isFileIgnored() aggressively caches
|
308
|
+
* results so there is no performance penalty for calling
|
309
|
+
* it twice with the same argument.
|
310
|
+
*/
|
311
|
+
if (pathMatches && !configs.isFileIgnored(entry.path)) {
|
312
|
+
unmatchedPatterns.delete(matcher.pattern);
|
313
|
+
}
|
314
|
+
|
315
|
+
return pathMatches || previousValue;
|
316
|
+
}, false)
|
317
|
+
: matchers.some(matcher => matcher.match(relativePath));
|
318
|
+
|
319
|
+
return matchesPattern && !configs.isFileIgnored(entry.path);
|
320
|
+
}
|
321
|
+
|
322
|
+
})).map(entry => entry.path);
|
323
|
+
|
324
|
+
// now check to see if we have any unmatched patterns
|
325
|
+
if (errorOnUnmatchedPattern && unmatchedPatterns.size > 0) {
|
326
|
+
throw new UnmatchedSearchPatternsError({
|
327
|
+
basePath,
|
328
|
+
unmatchedPatterns: [...unmatchedPatterns].map(
|
329
|
+
pattern => relativeToPatterns.get(pattern)
|
330
|
+
),
|
331
|
+
patterns,
|
332
|
+
rawPatterns
|
333
|
+
});
|
334
|
+
}
|
335
|
+
|
336
|
+
return filePaths;
|
337
|
+
}
|
338
|
+
|
339
|
+
/**
|
340
|
+
* Checks to see if there are any ignored results for a given search. This
|
341
|
+
* happens either when there are unmatched patterns during a search or if
|
342
|
+
* a search returns no results.
|
343
|
+
* @param {Object} options The options for this function.
|
344
|
+
* @param {string} options.basePath The directory to search.
|
345
|
+
* @param {Array<string>} options.patterns An array of glob patterns
|
346
|
+
* that were used in the original search.
|
347
|
+
* @param {Array<string>} options.rawPatterns An array of glob patterns
|
348
|
+
* as the user inputted them. Used for errors.
|
349
|
+
* @param {Array<string>} options.patternsToCheck An array of glob patterns
|
350
|
+
* to use for this check.
|
351
|
+
* @returns {void}
|
352
|
+
* @throws {NoFilesFoundError} If there is a pattern that doesn't match
|
353
|
+
* any files and `errorOnUnmatchedPattern` is true.
|
354
|
+
* @throws {AllFilesIgnoredError} If there is a pattern that matches files
|
355
|
+
* when there are no ignores.
|
356
|
+
*/
|
357
|
+
async function checkForIgnoredResults({
|
358
|
+
basePath,
|
359
|
+
patterns,
|
360
|
+
rawPatterns,
|
361
|
+
patternsToCheck = patterns
|
362
|
+
}) {
|
363
|
+
|
364
|
+
for (const pattern of patternsToCheck) {
|
365
|
+
|
366
|
+
const patternHasMatch = await globMatch({
|
367
|
+
basePath,
|
368
|
+
pattern
|
369
|
+
});
|
370
|
+
|
371
|
+
if (patternHasMatch) {
|
372
|
+
throw new AllFilesIgnoredError(
|
373
|
+
rawPatterns[patterns.indexOf(pattern)]
|
374
|
+
);
|
375
|
+
}
|
376
|
+
}
|
377
|
+
|
378
|
+
// if we get here there are truly no matches
|
379
|
+
throw new NoFilesFoundError(
|
380
|
+
rawPatterns[patterns.indexOf(patternsToCheck[0])],
|
381
|
+
true
|
382
|
+
);
|
383
|
+
}
|
384
|
+
|
385
|
+
/**
|
386
|
+
* Performs multiple glob searches in parallel.
|
387
|
+
* @param {Object} options The options for this function.
|
388
|
+
* @param {Map<string,GlobSearch>} options.searches
|
389
|
+
* An array of glob patterns to match.
|
390
|
+
* @param {FlatConfigArray} options.configs The config array to use for
|
391
|
+
* determining what to ignore.
|
392
|
+
* @param {boolean} options.errorOnUnmatchedPattern Determines if an
|
393
|
+
* unmatched glob pattern should throw an error.
|
394
|
+
* @returns {Promise<Array<string>>} An array of matching file paths
|
395
|
+
* or an empty array if there are no matches.
|
396
|
+
*/
|
397
|
+
async function globMultiSearch({ searches, configs, errorOnUnmatchedPattern }) {
|
398
|
+
|
399
|
+
/*
|
400
|
+
* For convenience, we normalized the search map into an array of objects.
|
401
|
+
* Next, we filter out all searches that have no patterns. This happens
|
402
|
+
* primarily for the cwd, which is prepopulated in the searches map as an
|
403
|
+
* optimization. However, if it has no patterns, it means all patterns
|
404
|
+
* occur outside of the cwd and we can safely filter out that search.
|
405
|
+
*/
|
406
|
+
const normalizedSearches = [...searches].map(
|
407
|
+
([basePath, { patterns, rawPatterns }]) => ({ basePath, patterns, rawPatterns })
|
408
|
+
).filter(({ patterns }) => patterns.length > 0);
|
409
|
+
|
410
|
+
const results = await Promise.allSettled(
|
411
|
+
normalizedSearches.map(
|
412
|
+
({ basePath, patterns, rawPatterns }) => globSearch({
|
413
|
+
basePath,
|
414
|
+
patterns,
|
415
|
+
rawPatterns,
|
416
|
+
configs,
|
417
|
+
errorOnUnmatchedPattern
|
418
|
+
})
|
419
|
+
)
|
420
|
+
);
|
421
|
+
|
422
|
+
const filePaths = [];
|
423
|
+
|
424
|
+
for (let i = 0; i < results.length; i++) {
|
425
|
+
|
426
|
+
const result = results[i];
|
427
|
+
const currentSearch = normalizedSearches[i];
|
428
|
+
|
429
|
+
if (result.status === "fulfilled") {
|
430
|
+
|
431
|
+
// if the search was successful just add the results
|
432
|
+
if (result.value.length > 0) {
|
433
|
+
filePaths.push(...result.value);
|
434
|
+
}
|
435
|
+
|
436
|
+
continue;
|
437
|
+
}
|
438
|
+
|
439
|
+
// if we make it here then there was an error
|
440
|
+
const error = result.reason;
|
441
|
+
|
442
|
+
// unexpected errors should be re-thrown
|
443
|
+
if (!error.basePath) {
|
444
|
+
throw error;
|
445
|
+
}
|
446
|
+
|
447
|
+
if (errorOnUnmatchedPattern) {
|
448
|
+
|
449
|
+
await checkForIgnoredResults({
|
450
|
+
...currentSearch,
|
451
|
+
patternsToCheck: error.patternsToCheck
|
452
|
+
});
|
453
|
+
|
454
|
+
}
|
455
|
+
|
456
|
+
}
|
457
|
+
|
458
|
+
return [...new Set(filePaths)];
|
459
|
+
|
460
|
+
}
|
461
|
+
|
100
462
|
/**
|
101
463
|
* Finds all files matching the options specified.
|
102
464
|
* @param {Object} args The arguments objects.
|
@@ -120,8 +482,10 @@ async function findFiles({
|
|
120
482
|
}) {
|
121
483
|
|
122
484
|
const results = [];
|
123
|
-
const globbyPatterns = [];
|
124
485
|
const missingPatterns = [];
|
486
|
+
let globbyPatterns = [];
|
487
|
+
let rawPatterns = [];
|
488
|
+
const searches = new Map([[cwd, { patterns: globbyPatterns, rawPatterns: [] }]]);
|
125
489
|
|
126
490
|
// check to see if we have explicit files and directories
|
127
491
|
const filePaths = patterns.map(filePath => path.resolve(cwd, filePath));
|
@@ -142,76 +506,25 @@ async function findFiles({
|
|
142
506
|
if (stat.isFile()) {
|
143
507
|
results.push({
|
144
508
|
filePath,
|
145
|
-
ignored: configs.
|
509
|
+
ignored: configs.isFileIgnored(filePath)
|
146
510
|
});
|
147
511
|
}
|
148
512
|
|
149
513
|
// directories need extensions attached
|
150
514
|
if (stat.isDirectory()) {
|
151
515
|
|
152
|
-
//
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
// patterns starting with ** always apply
|
162
|
-
if (filePattern.startsWith("**")) {
|
163
|
-
return true;
|
164
|
-
}
|
165
|
-
|
166
|
-
// patterns ending with * are not used for file search
|
167
|
-
if (filePattern.endsWith("*")) {
|
168
|
-
return false;
|
169
|
-
}
|
170
|
-
|
171
|
-
// not sure how to handle negated patterns yet
|
172
|
-
if (filePattern.startsWith("!")) {
|
173
|
-
return false;
|
174
|
-
}
|
175
|
-
|
176
|
-
// check if the pattern would be inside the config base path or not
|
177
|
-
const fullFilePattern = path.join(cwd, filePattern);
|
178
|
-
const patternRelativeToConfigBasePath = path.relative(configs.basePath, fullFilePattern);
|
179
|
-
|
180
|
-
if (patternRelativeToConfigBasePath.startsWith("..")) {
|
181
|
-
return false;
|
182
|
-
}
|
183
|
-
|
184
|
-
// check if the pattern matches
|
185
|
-
if (minimatch(filePath, path.dirname(fullFilePattern), { partial: true })) {
|
186
|
-
return true;
|
187
|
-
}
|
188
|
-
|
189
|
-
// check if the pattern is inside the directory or not
|
190
|
-
const patternRelativeToFilePath = path.relative(filePath, fullFilePattern);
|
191
|
-
|
192
|
-
if (patternRelativeToFilePath.startsWith("..")) {
|
193
|
-
return false;
|
194
|
-
}
|
195
|
-
|
196
|
-
return true;
|
197
|
-
})
|
198
|
-
.map(filePattern => {
|
199
|
-
if (filePattern.startsWith("**")) {
|
200
|
-
return path.join(pattern, filePattern);
|
201
|
-
}
|
202
|
-
|
203
|
-
// adjust the path to be relative to the cwd
|
204
|
-
return path.relative(
|
205
|
-
cwd,
|
206
|
-
path.join(configs.basePath, filePattern)
|
207
|
-
);
|
208
|
-
})
|
209
|
-
.map(normalizeToPosix);
|
210
|
-
|
211
|
-
if (filePatterns.length) {
|
212
|
-
globbyPatterns.push(...filePatterns);
|
516
|
+
// group everything in cwd together and split out others
|
517
|
+
if (isPathInside(filePath, cwd)) {
|
518
|
+
({ patterns: globbyPatterns, rawPatterns } = searches.get(cwd));
|
519
|
+
} else {
|
520
|
+
if (!searches.has(filePath)) {
|
521
|
+
searches.set(filePath, { patterns: [], rawPatterns: [] });
|
522
|
+
}
|
523
|
+
({ patterns: globbyPatterns, rawPatterns } = searches.get(filePath));
|
213
524
|
}
|
214
525
|
|
526
|
+
globbyPatterns.push(`${normalizeToPosix(filePath)}/**`);
|
527
|
+
rawPatterns.push(pattern);
|
215
528
|
}
|
216
529
|
|
217
530
|
return;
|
@@ -219,47 +532,37 @@ async function findFiles({
|
|
219
532
|
|
220
533
|
// save patterns for later use based on whether globs are enabled
|
221
534
|
if (globInputPaths && isGlobPattern(filePath)) {
|
222
|
-
globbyPatterns.push(pattern);
|
223
|
-
} else {
|
224
|
-
missingPatterns.push(pattern);
|
225
|
-
}
|
226
|
-
});
|
227
|
-
|
228
|
-
// note: globbyPatterns can be an empty array
|
229
|
-
const globbyResults = (await globby(globbyPatterns, {
|
230
|
-
cwd,
|
231
|
-
absolute: true,
|
232
|
-
ignore: configs.ignores.filter(matcher => typeof matcher === "string")
|
233
|
-
}));
|
234
|
-
|
235
|
-
// if there are no results, tell the user why
|
236
|
-
if (!results.length && !globbyResults.length) {
|
237
|
-
|
238
|
-
// try globby without ignoring anything
|
239
|
-
/* eslint-disable no-unreachable-loop -- We want to exit early. */
|
240
|
-
for (const globbyPattern of globbyPatterns) {
|
241
535
|
|
242
|
-
|
243
|
-
for await (const filePath of globby.stream(globbyPattern, { cwd, absolute: true })) {
|
536
|
+
const basePath = globParent(filePath);
|
244
537
|
|
245
|
-
|
246
|
-
|
538
|
+
// group in cwd if possible and split out others
|
539
|
+
if (isPathInside(basePath, cwd)) {
|
540
|
+
({ patterns: globbyPatterns, rawPatterns } = searches.get(cwd));
|
541
|
+
} else {
|
542
|
+
if (!searches.has(basePath)) {
|
543
|
+
searches.set(basePath, { patterns: [], rawPatterns: [] });
|
544
|
+
}
|
545
|
+
({ patterns: globbyPatterns, rawPatterns } = searches.get(basePath));
|
247
546
|
}
|
248
547
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
548
|
+
globbyPatterns.push(filePath);
|
549
|
+
rawPatterns.push(pattern);
|
550
|
+
} else {
|
551
|
+
missingPatterns.push(pattern);
|
253
552
|
}
|
254
|
-
|
255
|
-
|
256
|
-
}
|
553
|
+
});
|
257
554
|
|
258
555
|
// there were patterns that didn't match anything, tell the user
|
259
556
|
if (errorOnUnmatchedPattern && missingPatterns.length) {
|
260
557
|
throw new NoFilesFoundError(missingPatterns[0], globInputPaths);
|
261
558
|
}
|
262
559
|
|
560
|
+
// now we are safe to do the search
|
561
|
+
const globbyResults = await globMultiSearch({
|
562
|
+
searches,
|
563
|
+
configs,
|
564
|
+
errorOnUnmatchedPattern
|
565
|
+
});
|
263
566
|
|
264
567
|
return [
|
265
568
|
...results,
|