Skip to content

Commit 9761634

Browse files
committed
dofs: Match single-character globs
Teach find that a question mark matches one non-separator character so its glob surface covers the pattern documented by the AI find tool.
1 parent 2c0614a commit 9761634

2 files changed

Lines changed: 17 additions & 0 deletions

File tree

packages/dofs/src/fs/find.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ describe("find", () => {
5454
});
5555
});
5656

57+
it("matches ? as one non-separator character", async () => {
58+
await withDB(async (db) => {
59+
mkdir(db, "/a", {}, () => 0);
60+
await writeFile(db, "/a/a.ts", "", {}, () => 0);
61+
await writeFile(db, "/a/ab.ts", "", {}, () => 0);
62+
await writeFile(db, "/a/b.ts", "", {}, () => 0);
63+
const paths = find(db, "/a", "?.ts").map((entry) => entry.path);
64+
expect(paths).toEqual(["/a/a.ts", "/a/b.ts"]);
65+
});
66+
});
67+
5768
it("matches ** recursively", async () => {
5869
await withDB(async (db) => {
5970
mkdir(db, "/a/b/c", { recursive: true }, () => 0);

packages/dofs/src/fs/find.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ function walk(db: Database, parentInode: number, parentPath: string, out: Worksp
6565
// Compile a simple glob into a regex. Supported:
6666
// * matches any run of characters except '/'
6767
// ** matches any run of characters including '/'
68+
// ? matches one character except '/'
6869
// Anything else is a literal. Regex metacharacters in literals are
6970
// escaped so '.' in '*.ts' doesn't match an arbitrary character.
7071
function compileGlob(pattern: string): RegExp {
@@ -89,6 +90,11 @@ function compileGlob(pattern: string): RegExp {
8990
}
9091
continue;
9192
}
93+
if (ch === "?") {
94+
re += "[^/]";
95+
i += 1;
96+
continue;
97+
}
9298
if (REGEX_METACHARS.has(ch)) {
9399
re += `\\${ch}`;
94100
} else {

0 commit comments

Comments
 (0)