mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-10-13 07:47:46 +08:00
fix(core): exclude hidden glob matches before limiting results
This commit is contained in:
@@ -173,6 +173,8 @@ const layer = Layer.effect(
|
||||
...(input.hidden ? ["--hidden"] : []),
|
||||
...(input.follow ? ["--follow"] : []),
|
||||
`--glob=${input.pattern}`,
|
||||
// Positive globs override rg's hidden-file filter; exclude before applying the result limit.
|
||||
...(input.hidden ? [] : ["--glob=!**/.*"]),
|
||||
"--glob=!**/.git/**",
|
||||
".",
|
||||
],
|
||||
|
||||
@@ -6,13 +6,43 @@ import { AppNodeBuilder } from "@opencode/core/effect/app-node-builder"
|
||||
import { Location } from "@opencode/core/location"
|
||||
import { Ripgrep } from "@opencode/core/ripgrep"
|
||||
import { RelativePath } from "@opencode/core/schema"
|
||||
import { tmpdir } from "./fixture/tmpdir"
|
||||
import { tmpdir, tmpdirScoped } from "./fixture/tmpdir"
|
||||
import { testEffect } from "./lib/effect"
|
||||
import { tempLocationLayer } from "./fixture/location"
|
||||
|
||||
const it = testEffect(AppNodeBuilder.build(Ripgrep.node, [Location.node.replace(tempLocationLayer)]))
|
||||
|
||||
describe("Ripgrep", () => {
|
||||
for (const hidden of [undefined, false, true]) {
|
||||
for (const limit of hidden ? [10] : [1, 10]) {
|
||||
it.live(`glob honors hidden=${hidden} before limit=${limit}`, () =>
|
||||
Effect.gen(function* () {
|
||||
const tmp = yield* tmpdirScoped()
|
||||
yield* Effect.promise(() =>
|
||||
Promise.all(
|
||||
["src/visible.ts", ".hidden.ts", "src/.hidden.ts", ".hidden/nested.ts", ".git/config.ts"].map((file) =>
|
||||
Bun.write(path.join(tmp.path, file), "needle\n"),
|
||||
),
|
||||
),
|
||||
)
|
||||
const ripgrep = yield* Ripgrep.Service
|
||||
const files = yield* ripgrep.glob({
|
||||
cwd: tmp.path,
|
||||
pattern: "**/*.ts",
|
||||
limit,
|
||||
...(hidden === undefined ? {} : { hidden }),
|
||||
})
|
||||
|
||||
expect(files.map((item) => item.path).sort()).toEqual(
|
||||
(hidden ? [".hidden.ts", ".hidden/nested.ts", "src/.hidden.ts", "src/visible.ts"] : ["src/visible.ts"]).map(
|
||||
(file) => RelativePath.make(file),
|
||||
),
|
||||
)
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
it.live("globs files as an array", () =>
|
||||
Effect.acquireUseRelease(
|
||||
Effect.promise(() => tmpdir()),
|
||||
|
||||
@@ -17,7 +17,7 @@ import { GlobTool } from "@opencode/core/tool/plugin/glob"
|
||||
import { GrepTool } from "@opencode/core/tool/plugin/grep"
|
||||
import { Tool } from "@opencode/core/tool"
|
||||
import { location } from "./fixture/location"
|
||||
import { tmpdir } from "./fixture/tmpdir"
|
||||
import { tmpdir, tmpdirScoped } from "./fixture/tmpdir"
|
||||
import { it } from "./lib/effect"
|
||||
import { permissionLayer } from "./lib/permission"
|
||||
import { executeTool, registerToolPlugin, toolIdentity } from "./lib/tool"
|
||||
@@ -67,6 +67,45 @@ const call = (name: "glob" | "grep", input: unknown) => ({
|
||||
})
|
||||
|
||||
describe("search tools", () => {
|
||||
for (const hidden of [undefined, false, true]) {
|
||||
for (const limit of hidden ? [10] : [1, 10]) {
|
||||
it.live(`glob honors hidden=${hidden} before limit=${limit}`, () =>
|
||||
Effect.gen(function* () {
|
||||
const tmp = yield* tmpdirScoped()
|
||||
yield* Effect.promise(() =>
|
||||
Promise.all(
|
||||
["src/visible.ts", ".hidden.ts", "src/.hidden.ts", ".hidden/nested.ts", ".git/config.ts"].map((file) =>
|
||||
Bun.write(path.join(tmp.path, file), "needle\n"),
|
||||
),
|
||||
),
|
||||
)
|
||||
yield* withTools(tmp.path, (registry) =>
|
||||
Effect.gen(function* () {
|
||||
const result = yield* executeTool(
|
||||
registry,
|
||||
call("glob", { pattern: "**/*.ts", limit, ...(hidden === undefined ? {} : { hidden }) }),
|
||||
)
|
||||
const expected = hidden
|
||||
? [".hidden.ts", ".hidden/nested.ts", "src/.hidden.ts", "src/visible.ts"]
|
||||
: ["src/visible.ts"]
|
||||
|
||||
expect(result.status).toBe("completed")
|
||||
expect(result.output).toHaveLength(expected.length)
|
||||
expect(result.output).toEqual(
|
||||
expect.arrayContaining(expected.map((file) => ({ path: path.normalize(file), type: "file" }))),
|
||||
)
|
||||
expect(result.metadata).toEqual({ count: expected.length, truncated: false })
|
||||
expect(result.content).toHaveLength(1)
|
||||
expect(result.content?.[0]?.type === "text" ? result.content[0].text.split("\n").sort() : []).toEqual(
|
||||
expected.map((file) => path.join(tmp.path, file)).sort(),
|
||||
)
|
||||
}),
|
||||
)
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
it.live("bounds omitted glob and grep limits", () =>
|
||||
Effect.acquireUseRelease(
|
||||
Effect.promise(() => tmpdir()),
|
||||
|
||||
Reference in New Issue
Block a user