Skip to content

Commit 5402cab

Browse files
Merge pull request #3452 from github/robertbrignull/findDirWithFile
Move findDirWithFile to files.ts
2 parents dbd5078 + fe6dc8a commit 5402cab

4 files changed

Lines changed: 88 additions & 90 deletions

File tree

extensions/ql-vscode/src/common/files.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,32 @@ export function findCommonParentDir(...paths: string[]): string {
176176
function isTopLevelPath(path: string): boolean {
177177
return dirname(path) === path;
178178
}
179+
180+
/**
181+
* Recursively looks for a file in a directory. If the file exists, then returns the directory containing the file.
182+
*
183+
* @param dir The directory to search
184+
* @param toFind The file to recursively look for in this directory
185+
*
186+
* @returns the directory containing the file, or undefined if not found.
187+
*/
188+
export async function findDirWithFile(
189+
dir: string,
190+
...toFind: string[]
191+
): Promise<string | undefined> {
192+
if (!(await stat(dir)).isDirectory()) {
193+
return;
194+
}
195+
const files = await readdir(dir);
196+
if (toFind.some((file) => files.includes(file))) {
197+
return dir;
198+
}
199+
for (const file of files) {
200+
const newPath = join(dir, file);
201+
const result = await findDirWithFile(newPath, ...toFind);
202+
if (result) {
203+
return result;
204+
}
205+
}
206+
return;
207+
}

extensions/ql-vscode/src/databases/database-fetcher.ts

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import {
1010
pathExists,
1111
createWriteStream,
1212
remove,
13-
stat,
14-
readdir,
1513
} from "fs-extra";
1614
import { basename, join } from "path";
1715
import type { Octokit } from "@octokit/rest";
@@ -39,6 +37,7 @@ import { getLanguageDisplayName } from "../common/query-language";
3937
import type { DatabaseOrigin } from "./local-databases/database-origin";
4038
import { createTimeoutSignal } from "../common/fetch-stream";
4139
import type { App } from "../common/app";
40+
import { findDirWithFile } from "../common/files";
4241

4342
/**
4443
* Prompts a user to fetch a database from a remote location. Database is assumed to be an archive file.
@@ -588,36 +587,6 @@ function isFile(databaseUrl: string) {
588587
return Uri.parse(databaseUrl).scheme === "file";
589588
}
590589

591-
/**
592-
* Recursively looks for a file in a directory. If the file exists, then returns the directory containing the file.
593-
*
594-
* @param dir The directory to search
595-
* @param toFind The file to recursively look for in this directory
596-
*
597-
* @returns the directory containing the file, or undefined if not found.
598-
*/
599-
// exported for testing
600-
export async function findDirWithFile(
601-
dir: string,
602-
...toFind: string[]
603-
): Promise<string | undefined> {
604-
if (!(await stat(dir)).isDirectory()) {
605-
return;
606-
}
607-
const files = await readdir(dir);
608-
if (toFind.some((file) => files.includes(file))) {
609-
return dir;
610-
}
611-
for (const file of files) {
612-
const newPath = join(dir, file);
613-
const result = await findDirWithFile(newPath, ...toFind);
614-
if (result) {
615-
return result;
616-
}
617-
}
618-
return;
619-
}
620-
621590
export async function convertGithubNwoToDatabaseUrl(
622591
nwo: string,
623592
octokit: Octokit,

extensions/ql-vscode/test/unit-tests/common/files.test.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { join, parse } from "path";
33
import {
44
containsPath,
55
findCommonParentDir,
6+
findDirWithFile,
67
gatherQlFiles,
78
getDirectoryNamesInsidePath,
89
pathsEqual,
@@ -11,7 +12,13 @@ import {
1112
} from "../../../src/common/files";
1213
import type { DirResult } from "tmp";
1314
import { dirSync } from "tmp";
14-
import { ensureDirSync, symlinkSync, writeFileSync } from "fs-extra";
15+
import {
16+
createFileSync,
17+
ensureDirSync,
18+
mkdirSync,
19+
symlinkSync,
20+
writeFileSync,
21+
} from "fs-extra";
1522
import "../../matchers/toEqualPath";
1623

1724
describe("files", () => {
@@ -592,3 +599,52 @@ describe("findCommonParentDir", () => {
592599
expect(commonDir).toEqualPath(dataDir);
593600
});
594601
});
602+
603+
describe("findDirWithFile", () => {
604+
let dir: DirResult;
605+
beforeEach(() => {
606+
dir = dirSync({ unsafeCleanup: true });
607+
createFile("a");
608+
createFile("b");
609+
createFile("c");
610+
611+
createDir("dir1");
612+
createFile("dir1", "d");
613+
createFile("dir1", "e");
614+
createFile("dir1", "f");
615+
616+
createDir("dir2");
617+
createFile("dir2", "g");
618+
createFile("dir2", "h");
619+
createFile("dir2", "i");
620+
621+
createDir("dir2", "dir3");
622+
createFile("dir2", "dir3", "j");
623+
createFile("dir2", "dir3", "k");
624+
createFile("dir2", "dir3", "l");
625+
});
626+
627+
it("should find files", async () => {
628+
expect(await findDirWithFile(dir.name, "k")).toBe(
629+
join(dir.name, "dir2", "dir3"),
630+
);
631+
expect(await findDirWithFile(dir.name, "h")).toBe(join(dir.name, "dir2"));
632+
expect(await findDirWithFile(dir.name, "z", "a")).toBe(dir.name);
633+
// there's some slight indeterminism when more than one name exists
634+
// but in general, this will find files in the current directory before
635+
// finding files in sub-dirs
636+
expect(await findDirWithFile(dir.name, "k", "a")).toBe(dir.name);
637+
});
638+
639+
it("should not find files", async () => {
640+
expect(await findDirWithFile(dir.name, "x", "y", "z")).toBeUndefined();
641+
});
642+
643+
function createFile(...segments: string[]) {
644+
createFileSync(join(dir.name, ...segments));
645+
}
646+
647+
function createDir(...segments: string[]) {
648+
mkdirSync(join(dir.name, ...segments));
649+
}
650+
});

extensions/ql-vscode/test/vscode-tests/no-workspace/databases/database-fetcher.test.ts

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
1-
import { join } from "path";
2-
import { createFileSync, mkdirSync } from "fs-extra";
3-
import type { DirResult } from "tmp";
4-
import { dirSync } from "tmp";
51
import { window } from "vscode";
62

7-
import {
8-
convertGithubNwoToDatabaseUrl,
9-
findDirWithFile,
10-
} from "../../../../src/databases/database-fetcher";
3+
import { convertGithubNwoToDatabaseUrl } from "../../../../src/databases/database-fetcher";
114
import type { Octokit } from "@octokit/rest";
125
import {
136
mockedObject,
@@ -201,53 +194,4 @@ describe("database-fetcher", () => {
201194
});
202195
});
203196
});
204-
205-
describe("findDirWithFile", () => {
206-
let dir: DirResult;
207-
beforeEach(() => {
208-
dir = dirSync({ unsafeCleanup: true });
209-
createFile("a");
210-
createFile("b");
211-
createFile("c");
212-
213-
createDir("dir1");
214-
createFile("dir1", "d");
215-
createFile("dir1", "e");
216-
createFile("dir1", "f");
217-
218-
createDir("dir2");
219-
createFile("dir2", "g");
220-
createFile("dir2", "h");
221-
createFile("dir2", "i");
222-
223-
createDir("dir2", "dir3");
224-
createFile("dir2", "dir3", "j");
225-
createFile("dir2", "dir3", "k");
226-
createFile("dir2", "dir3", "l");
227-
});
228-
229-
it("should find files", async () => {
230-
expect(await findDirWithFile(dir.name, "k")).toBe(
231-
join(dir.name, "dir2", "dir3"),
232-
);
233-
expect(await findDirWithFile(dir.name, "h")).toBe(join(dir.name, "dir2"));
234-
expect(await findDirWithFile(dir.name, "z", "a")).toBe(dir.name);
235-
// there's some slight indeterminism when more than one name exists
236-
// but in general, this will find files in the current directory before
237-
// finding files in sub-dirs
238-
expect(await findDirWithFile(dir.name, "k", "a")).toBe(dir.name);
239-
});
240-
241-
it("should not find files", async () => {
242-
expect(await findDirWithFile(dir.name, "x", "y", "z")).toBeUndefined();
243-
});
244-
245-
function createFile(...segments: string[]) {
246-
createFileSync(join(dir.name, ...segments));
247-
}
248-
249-
function createDir(...segments: string[]) {
250-
mkdirSync(join(dir.name, ...segments));
251-
}
252-
});
253197
});

0 commit comments

Comments
 (0)