diff options
Diffstat (limited to 'std/fs/expand_glob.ts')
-rw-r--r-- | std/fs/expand_glob.ts | 82 |
1 files changed, 42 insertions, 40 deletions
diff --git a/std/fs/expand_glob.ts b/std/fs/expand_glob.ts index 386f61ad5..803c67cdf 100644 --- a/std/fs/expand_glob.ts +++ b/std/fs/expand_glob.ts @@ -8,9 +8,15 @@ import { joinGlobs, normalize, } from "../path/mod.ts"; -import { WalkEntry, walk, walkSync } from "./walk.ts"; +import { + WalkEntry, + createWalkEntry, + createWalkEntrySync, + walk, + walkSync, +} from "./walk.ts"; import { assert } from "../testing/asserts.ts"; -const { cwd, stat, statSync } = Deno; +const { cwd } = Deno; type FileInfo = Deno.FileInfo; export interface ExpandGlobOptions extends GlobOptions { @@ -48,6 +54,12 @@ function throwUnlessNotFound(error: Error): void { } } +function comparePath(a: WalkEntry, b: WalkEntry): number { + if (a.path < b.path) return -1; + if (a.path > b.path) return 1; + return 0; +} + /** * Expand the glob string from the specified `root` directory and yield each * result as a `WalkEntry` object. @@ -73,8 +85,8 @@ export async function* expandGlob( const excludePatterns = exclude .map(resolveFromRoot) .map((s: string): RegExp => globToRegExp(s, globOptions)); - const shouldInclude = (filename: string): boolean => - !excludePatterns.some((p: RegExp): boolean => !!filename.match(p)); + const shouldInclude = (path: string): boolean => + !excludePatterns.some((p: RegExp): boolean => !!path.match(p)); const { segments, hasTrailingSep, winRoot } = split(resolveFromRoot(glob)); let fixedRoot = winRoot != undefined ? winRoot : "/"; @@ -86,7 +98,7 @@ export async function* expandGlob( let fixedRootInfo: WalkEntry; try { - fixedRootInfo = { filename: fixedRoot, info: await stat(fixedRoot) }; + fixedRootInfo = await createWalkEntry(fixedRoot); } catch (error) { return throwUnlessNotFound(error); } @@ -95,29 +107,29 @@ export async function* expandGlob( walkInfo: WalkEntry, globSegment: string ): AsyncIterableIterator<WalkEntry> { - if (!walkInfo.info.isDirectory) { + if (!walkInfo.isDirectory) { return; } else if (globSegment == "..") { - const parentPath = joinGlobs([walkInfo.filename, ".."], globOptions); + const parentPath = joinGlobs([walkInfo.path, ".."], globOptions); try { if (shouldInclude(parentPath)) { - return yield { filename: parentPath, info: await stat(parentPath) }; + return yield await createWalkEntry(parentPath); } } catch (error) { throwUnlessNotFound(error); } return; } else if (globSegment == "**") { - return yield* walk(walkInfo.filename, { + return yield* walk(walkInfo.path, { includeFiles: false, skip: excludePatterns, }); } - yield* walk(walkInfo.filename, { + yield* walk(walkInfo.path, { maxDepth: 1, match: [ globToRegExp( - joinGlobs([walkInfo.filename, globSegment], globOptions), + joinGlobs([walkInfo.path, globSegment], globOptions), globOptions ), ], @@ -129,27 +141,22 @@ export async function* expandGlob( for (const segment of segments) { // Advancing the list of current matches may introduce duplicates, so we // pass everything through this Map. - const nextMatchMap: Map<string, FileInfo> = new Map(); + const nextMatchMap: Map<string, WalkEntry> = new Map(); for (const currentMatch of currentMatches) { for await (const nextMatch of advanceMatch(currentMatch, segment)) { - nextMatchMap.set(nextMatch.filename, nextMatch.info); + nextMatchMap.set(nextMatch.path, nextMatch); } } - currentMatches = [...nextMatchMap].sort().map( - ([filename, info]): WalkEntry => ({ - filename, - info, - }) - ); + currentMatches = [...nextMatchMap.values()].sort(comparePath); } if (hasTrailingSep) { currentMatches = currentMatches.filter( - ({ info }): boolean => info.isDirectory + (entry: WalkEntry): boolean => entry.isDirectory ); } if (!includeDirs) { currentMatches = currentMatches.filter( - ({ info }): boolean => !info.isDirectory + (entry: WalkEntry): boolean => !entry.isDirectory ); } yield* currentMatches; @@ -177,8 +184,8 @@ export function* expandGlobSync( const excludePatterns = exclude .map(resolveFromRoot) .map((s: string): RegExp => globToRegExp(s, globOptions)); - const shouldInclude = (filename: string): boolean => - !excludePatterns.some((p: RegExp): boolean => !!filename.match(p)); + const shouldInclude = (path: string): boolean => + !excludePatterns.some((p: RegExp): boolean => !!path.match(p)); const { segments, hasTrailingSep, winRoot } = split(resolveFromRoot(glob)); let fixedRoot = winRoot != undefined ? winRoot : "/"; @@ -190,7 +197,7 @@ export function* expandGlobSync( let fixedRootInfo: WalkEntry; try { - fixedRootInfo = { filename: fixedRoot, info: statSync(fixedRoot) }; + fixedRootInfo = createWalkEntrySync(fixedRoot); } catch (error) { return throwUnlessNotFound(error); } @@ -199,29 +206,29 @@ export function* expandGlobSync( walkInfo: WalkEntry, globSegment: string ): IterableIterator<WalkEntry> { - if (!walkInfo.info.isDirectory) { + if (!walkInfo.isDirectory) { return; } else if (globSegment == "..") { - const parentPath = joinGlobs([walkInfo.filename, ".."], globOptions); + const parentPath = joinGlobs([walkInfo.path, ".."], globOptions); try { if (shouldInclude(parentPath)) { - return yield { filename: parentPath, info: statSync(parentPath) }; + return yield createWalkEntrySync(parentPath); } } catch (error) { throwUnlessNotFound(error); } return; } else if (globSegment == "**") { - return yield* walkSync(walkInfo.filename, { + return yield* walkSync(walkInfo.path, { includeFiles: false, skip: excludePatterns, }); } - yield* walkSync(walkInfo.filename, { + yield* walkSync(walkInfo.path, { maxDepth: 1, match: [ globToRegExp( - joinGlobs([walkInfo.filename, globSegment], globOptions), + joinGlobs([walkInfo.path, globSegment], globOptions), globOptions ), ], @@ -233,27 +240,22 @@ export function* expandGlobSync( for (const segment of segments) { // Advancing the list of current matches may introduce duplicates, so we // pass everything through this Map. - const nextMatchMap: Map<string, FileInfo> = new Map(); + const nextMatchMap: Map<string, WalkEntry> = new Map(); for (const currentMatch of currentMatches) { for (const nextMatch of advanceMatch(currentMatch, segment)) { - nextMatchMap.set(nextMatch.filename, nextMatch.info); + nextMatchMap.set(nextMatch.path, nextMatch); } } - currentMatches = [...nextMatchMap].sort().map( - ([filename, info]): WalkEntry => ({ - filename, - info, - }) - ); + currentMatches = [...nextMatchMap.values()].sort(comparePath); } if (hasTrailingSep) { currentMatches = currentMatches.filter( - ({ info }): boolean => info.isDirectory + (entry: WalkEntry): boolean => entry.isDirectory ); } if (!includeDirs) { currentMatches = currentMatches.filter( - ({ info }): boolean => !info.isDirectory + (entry: WalkEntry): boolean => !entry.isDirectory ); } yield* currentMatches; |