@@ -15,7 +15,6 @@ const fsp = fs.promises;
1515const isGlob = require ( "is-glob" ) ;
1616const hash = require ( "../cli-engine/hash" ) ;
1717const minimatch = require ( "minimatch" ) ;
18- const util = require ( "util" ) ;
1918const fswalk = require ( "@nodelib/fs.walk" ) ;
2019const globParent = require ( "glob-parent" ) ;
2120const isPathInside = require ( "is-path-inside" ) ;
@@ -24,7 +23,6 @@ const isPathInside = require("is-path-inside");
2423// Fixup references
2524//-----------------------------------------------------------------------------
2625
27- const doFsWalk = util . promisify ( fswalk . walk ) ;
2826const Minimatch = minimatch . Minimatch ;
2927const MINIMATCH_OPTIONS = { dot : true } ;
3028
@@ -270,56 +268,92 @@ async function globSearch({
270268 */
271269 const unmatchedPatterns = new Set ( [ ...relativeToPatterns . keys ( ) ] ) ;
272270
273- const filePaths = ( await doFsWalk ( basePath , {
271+ const filePaths = ( await new Promise ( ( resolve , reject ) => {
274272
275- deepFilter ( entry ) {
276- const relativePath = normalizeToPosix ( path . relative ( basePath , entry . path ) ) ;
277- const matchesPattern = matchers . some ( matcher => matcher . match ( relativePath , true ) ) ;
278-
279- return matchesPattern && ! configs . isDirectoryIgnored ( entry . path ) ;
280- } ,
281- entryFilter ( entry ) {
282- const relativePath = normalizeToPosix ( path . relative ( basePath , entry . path ) ) ;
273+ let promiseRejected = false ;
283274
284- // entries may be directories or files so filter out directories
285- if ( entry . dirent . isDirectory ( ) ) {
275+ /**
276+ * Wraps a boolean-returning filter function. The wrapped function will reject the promise if an error occurs.
277+ * @param {Function } filter A filter function to wrap.
278+ * @returns {Function } A function similar to the wrapped filter that rejects the promise if an error occurs.
279+ */
280+ function wrapFilter ( filter ) {
281+ return ( ...args ) => {
282+
283+ // No need to run the filter if an error has been thrown.
284+ if ( ! promiseRejected ) {
285+ try {
286+ return filter ( ...args ) ;
287+ } catch ( error ) {
288+ promiseRejected = true ;
289+ reject ( error ) ;
290+ }
291+ }
286292 return false ;
287- }
293+ } ;
294+ }
288295
289- /*
290- * Optimization: We need to track when patterns are left unmatched
291- * and so we use `unmatchedPatterns` to do that. There is a bit of
292- * complexity here because the same file can be matched by more than
293- * one pattern. So, when we start, we actually need to test every
294- * pattern against every file. Once we know there are no remaining
295- * unmatched patterns, then we can switch to just looking for the
296- * first matching pattern for improved speed.
297- */
298- const matchesPattern = unmatchedPatterns . size > 0
299- ? matchers . reduce ( ( previousValue , matcher ) => {
300- const pathMatches = matcher . match ( relativePath ) ;
296+ fswalk . walk (
297+ basePath ,
298+ {
299+ deepFilter : wrapFilter ( entry => {
300+ const relativePath = normalizeToPosix ( path . relative ( basePath , entry . path ) ) ;
301+ const matchesPattern = matchers . some ( matcher => matcher . match ( relativePath , true ) ) ;
302+
303+ return matchesPattern && ! configs . isDirectoryIgnored ( entry . path ) ;
304+ } ) ,
305+ entryFilter : wrapFilter ( entry => {
306+ const relativePath = normalizeToPosix ( path . relative ( basePath , entry . path ) ) ;
307+
308+ // entries may be directories or files so filter out directories
309+ if ( entry . dirent . isDirectory ( ) ) {
310+ return false ;
311+ }
301312
302313 /*
303- * We updated the unmatched patterns set only if the path
304- * matches and the file isn't ignored. If the file is
305- * ignored, that means there wasn't a match for the
306- * pattern so it should not be removed.
307- *
308- * Performance note: isFileIgnored() aggressively caches
309- * results so there is no performance penalty for calling
310- * it twice with the same argument.
314+ * Optimization: We need to track when patterns are left unmatched
315+ * and so we use `unmatchedPatterns` to do that. There is a bit of
316+ * complexity here because the same file can be matched by more than
317+ * one pattern. So, when we start, we actually need to test every
318+ * pattern against every file. Once we know there are no remaining
319+ * unmatched patterns, then we can switch to just looking for the
320+ * first matching pattern for improved speed.
311321 */
312- if ( pathMatches && ! configs . isFileIgnored ( entry . path ) ) {
313- unmatchedPatterns . delete ( matcher . pattern ) ;
314- }
315-
316- return pathMatches || previousValue ;
317- } , false )
318- : matchers . some ( matcher => matcher . match ( relativePath ) ) ;
319-
320- return matchesPattern && ! configs . isFileIgnored ( entry . path ) ;
321- }
322-
322+ const matchesPattern = unmatchedPatterns . size > 0
323+ ? matchers . reduce ( ( previousValue , matcher ) => {
324+ const pathMatches = matcher . match ( relativePath ) ;
325+
326+ /*
327+ * We updated the unmatched patterns set only if the path
328+ * matches and the file isn't ignored. If the file is
329+ * ignored, that means there wasn't a match for the
330+ * pattern so it should not be removed.
331+ *
332+ * Performance note: isFileIgnored() aggressively caches
333+ * results so there is no performance penalty for calling
334+ * it twice with the same argument.
335+ */
336+ if ( pathMatches && ! configs . isFileIgnored ( entry . path ) ) {
337+ unmatchedPatterns . delete ( matcher . pattern ) ;
338+ }
339+
340+ return pathMatches || previousValue ;
341+ } , false )
342+ : matchers . some ( matcher => matcher . match ( relativePath ) ) ;
343+
344+ return matchesPattern && ! configs . isFileIgnored ( entry . path ) ;
345+ } )
346+ } ,
347+ ( error , entries ) => {
348+
349+ // If the promise is already rejected, calling `resolve` or `reject` will do nothing.
350+ if ( error ) {
351+ reject ( error ) ;
352+ } else {
353+ resolve ( entries ) ;
354+ }
355+ }
356+ ) ;
323357 } ) ) . map ( entry => entry . path ) ;
324358
325359 // now check to see if we have any unmatched patterns
0 commit comments