diff --git a/src/fsAsync.spec.ts b/src/fsAsync.spec.ts index b4fee377249..8f4b44bab8e 100644 --- a/src/fsAsync.spec.ts +++ b/src/fsAsync.spec.ts @@ -110,5 +110,22 @@ describe("fsAsync", () => { .sort(); return expect(gotFileNames).to.deep.equal(expectFiles); }); + + it("should support maximum recursion depth", async () => { + const results = await fsAsync.readdirRecursive({ path: baseDir, maxDepth: 2 }); + + const gotFileNames = results.map((r) => r.name).sort(); + const expectFiles = [".hidden", "visible", "subdir/subfile", "node_modules/subfile"]; + const expectPaths = expectFiles.map((file) => path.join(baseDir, file)).sort(); + return expect(gotFileNames).to.deep.equal(expectPaths); + }); + + it("should ignore invalid maximum recursion depth", async () => { + const results = await fsAsync.readdirRecursive({ path: baseDir, maxDepth: 0 }); + + const gotFileNames = results.map((r) => r.name).sort(); + const expectFiles = files.map((file) => path.join(baseDir, file)).sort(); + return expect(gotFileNames).to.deep.equal(expectFiles); + }); }); }); diff --git a/src/fsAsync.ts b/src/fsAsync.ts index 26123f9636b..33547f083c1 100644 --- a/src/fsAsync.ts +++ b/src/fsAsync.ts @@ -12,6 +12,8 @@ export interface ReaddirRecursiveOpts { isGitIgnore?: boolean; // Files in the ignore array to include. include?: string[]; + // Maximum depth to recurse. + maxDepth?: number; } export interface ReaddirRecursiveFile { @@ -22,6 +24,7 @@ export interface ReaddirRecursiveFile { async function readdirRecursiveHelper(options: { path: string; filter: (p: string) => boolean; + maxDepth: number; }): Promise { const dirContents = readdirSync(options.path); const fullPaths = dirContents.map((n) => join(options.path, n)); @@ -35,7 +38,11 @@ async function readdirRecursiveHelper(options: { if (!fstat.isDirectory()) { continue; } - filePromises.push(readdirRecursiveHelper({ path: p, filter: options.filter })); + if (options.maxDepth > 1) { + filePromises.push( + readdirRecursiveHelper({ path: p, filter: options.filter, maxDepth: options.maxDepth - 1 }), + ); + } } const files = await Promise.all(filePromises); @@ -70,8 +77,10 @@ export async function readdirRecursive( return rule(t); }); }; + const maxDepth = options.maxDepth && options.maxDepth > 0 ? options.maxDepth : Infinity; return await readdirRecursiveHelper({ path: options.path, filter: filter, + maxDepth, }); }