fix(core): handle oversized ripgrep matches
This commit is contained in:
parent
9b49e7bec9
commit
0261f04b90
2 changed files with 25 additions and 5 deletions
|
|
@ -16,7 +16,6 @@ import { RipgrepBinary } from "./ripgrep/binary"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ERROR_BYTES = 8 * 1024
|
const ERROR_BYTES = 8 * 1024
|
||||||
const MAX_RECORD_BYTES = 64 * 1024
|
|
||||||
const MAX_SUBMATCHES = 100
|
const MAX_SUBMATCHES = 100
|
||||||
|
|
||||||
const RawMatch = Schema.Struct({
|
const RawMatch = Schema.Struct({
|
||||||
|
|
@ -231,10 +230,8 @@ const layer = Layer.effect(
|
||||||
input.file ?? ".",
|
input.file ?? ".",
|
||||||
],
|
],
|
||||||
parse: (line) =>
|
parse: (line) =>
|
||||||
(Buffer.byteLength(line, "utf8") > MAX_RECORD_BYTES
|
decodeJsonRecord(line).pipe(
|
||||||
? Effect.fail(failure(`Ripgrep JSON record exceeded ${MAX_RECORD_BYTES} bytes`))
|
Effect.mapError((cause) => failure("Invalid ripgrep JSON output", cause)),
|
||||||
: decodeJsonRecord(line).pipe(Effect.mapError((cause) => failure("Invalid ripgrep JSON output", cause)))
|
|
||||||
).pipe(
|
|
||||||
Effect.flatMap((json) => {
|
Effect.flatMap((json) => {
|
||||||
if (!json || typeof json !== "object" || !("type" in json) || json.type !== "match")
|
if (!json || typeof json !== "object" || !("type" in json) || json.type !== "match")
|
||||||
return Effect.succeed(undefined)
|
return Effect.succeed(undefined)
|
||||||
|
|
|
||||||
|
|
@ -62,4 +62,27 @@ describe("Ripgrep", () => {
|
||||||
(tmp) => Effect.promise(() => tmp[Symbol.asyncDispose]()),
|
(tmp) => Effect.promise(() => tmp[Symbol.asyncDispose]()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
it.live("returns a bounded preview for matches on oversized lines", () =>
|
||||||
|
Effect.acquireUseRelease(
|
||||||
|
Effect.promise(() => tmpdir()),
|
||||||
|
(tmp) =>
|
||||||
|
Effect.gen(function* () {
|
||||||
|
yield* Effect.promise(() => fs.writeFile(path.join(tmp.path, "generated.ts"), `Cloudflare${"x".repeat(70 * 1024)}\n`))
|
||||||
|
|
||||||
|
const matches = yield* (yield* Ripgrep.Service).grep({
|
||||||
|
cwd: tmp.path,
|
||||||
|
pattern: "Cloudflare",
|
||||||
|
limit: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(matches).toHaveLength(1)
|
||||||
|
expect(matches[0]?.entry.path).toBe(RelativePath.make("generated.ts"))
|
||||||
|
expect(matches[0]?.text).toHaveLength(2_003)
|
||||||
|
expect(matches[0]?.text.endsWith("...")).toBe(true)
|
||||||
|
expect(matches[0]?.submatches).toEqual([{ text: "Cloudflare", start: 0, end: 10 }])
|
||||||
|
}),
|
||||||
|
(tmp) => Effect.promise(() => tmp[Symbol.asyncDispose]()),
|
||||||
|
),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue