Skip to content

Commit aab665d

Browse files
committed
fix(list-files): checking cwd before invoking rg (#558)
1 parent f737649 commit aab665d

3 files changed

Lines changed: 46 additions & 0 deletions

File tree

src/services/glob/__tests__/list-files-limit.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ vi.mock("../../../utils/path", () => ({
2323
arePathsEqual: vi.fn().mockReturnValue(false),
2424
}))
2525

26+
vi.mock("../../../services/roo-config", () => ({
27+
directoryExists: vi.fn().mockResolvedValue(true),
28+
}))
29+
2630
import * as childProcess from "child_process"
2731

2832
const createMockRipgrepProcess = (chunks: string[] = [], exitCode = 0) => ({

src/services/glob/__tests__/list-files.spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import * as path from "path"
22
import * as childProcess from "child_process"
33
import { listFiles } from "../list-files"
4+
import { directoryExists } from "../../../services/roo-config"
45

56
vi.mock("child_process")
67
vi.mock("fs")
8+
vi.mock("../../../services/roo-config", () => ({
9+
directoryExists: vi.fn().mockResolvedValue(true),
10+
}))
711
vi.mock("vscode", () => ({
812
env: {
913
appRoot: "/mock/vscode/app/root",
@@ -48,6 +52,7 @@ vi.mock("fs", () => ({
4852
access: vi.fn().mockRejectedValue(new Error("Not found")),
4953
readFile: vi.fn().mockResolvedValue(""),
5054
readdir: vi.fn().mockResolvedValue([]),
55+
stat: vi.fn().mockResolvedValue({ isDirectory: () => true }),
5156
},
5257
}))
5358

@@ -93,6 +98,10 @@ function resetFsPromiseMocks() {
9398
vi.mocked(fs.promises.readFile).mockResolvedValue("")
9499
vi.mocked(fs.promises.readdir).mockReset()
95100
vi.mocked(fs.promises.readdir).mockResolvedValue([])
101+
vi.mocked(fs.promises.stat).mockReset()
102+
vi.mocked(fs.promises.stat).mockResolvedValue({ isDirectory: () => true } as any)
103+
vi.mocked(directoryExists).mockReset()
104+
vi.mocked(directoryExists).mockResolvedValue(true)
96105
}
97106

98107
describe("list-files symlink support", () => {
@@ -403,3 +412,31 @@ describe("buildRecursiveArgs edge cases", () => {
403412
expect(args).not.toContain("--no-ignore")
404413
})
405414
})
415+
416+
describe("listFiles nonexistent directory", () => {
417+
beforeEach(() => {
418+
vi.clearAllMocks()
419+
resetFsPromiseMocks()
420+
})
421+
422+
it("should throw a clear error instead of a misleading ENOENT naming the executable", async () => {
423+
vi.mocked(directoryExists).mockResolvedValue(false)
424+
425+
await expect(listFiles("/nonexistent/path", true, 100)).rejects.toThrow(
426+
"Cannot list files: directory does not exist:",
427+
)
428+
429+
// spawn should never be called when the directory doesn't exist
430+
expect(vi.mocked(childProcess.spawn)).not.toHaveBeenCalled()
431+
})
432+
433+
it("should report the missing directory even when ripgrep binary is also unavailable", async () => {
434+
vi.mocked(directoryExists).mockResolvedValue(false)
435+
const { getBinPath } = await import("../../ripgrep")
436+
vi.mocked(getBinPath).mockRejectedValue(new Error("Could not find ripgrep binary"))
437+
438+
await expect(listFiles("/nonexistent/path", true, 100)).rejects.toThrow(
439+
"Cannot list files: directory does not exist:",
440+
)
441+
})
442+
})

src/services/glob/list-files.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as vscode from "vscode"
66
import ignore from "ignore"
77
import { arePathsEqual } from "../../utils/path"
88
import { getBinPath } from "../../services/ripgrep"
9+
import { directoryExists } from "../../services/roo-config"
910
import { DIRS_TO_IGNORE } from "./constants"
1011

1112
/**
@@ -36,6 +37,10 @@ export async function listFiles(dirPath: string, recursive: boolean, limit: numb
3637
return [[], false]
3738
}
3839

40+
if (!(await directoryExists(path.resolve(dirPath)))) {
41+
throw new Error(`Cannot list files: directory does not exist: ${path.resolve(dirPath)}`)
42+
}
43+
3944
// Handle special directories
4045
const specialResult = await handleSpecialDirectories(dirPath)
4146

0 commit comments

Comments
 (0)