mirror of
https://github.com/stablyai/orca.git
synced 2026-11-02 01:57:57 +00:00
* perf(wsl): run ripgrep on the Windows host for drive-path projects A project stored on a Windows drive (C:\...) with the WSL runtime selected ran quick open, file-path search, content search and Markdown listing through wsl.exe and the Linux rg reading /mnt/c over drvfs. rg only reads files, so it has no git index whose stat cache two writers could thrash; the host binary reads NTFS directly. Measured on a 21.6k-file clone on C: (Windows 11, Ubuntu-24.04): content search WSL rg 3.5 s -> host rg.exe 0.19 s file listing WSL rg 0.14 s + ~65 ms wsl.exe spawn -> host 0.03 s Git routing is intentionally unchanged: alternating Windows git and WSL git on the same index forced a full ~250 s rehash on the next WSL git status. WSL UNC roots and non-drive roots keep their existing routing. * fix(search): keep host rg results whole when files only WSL can open exist Windows rg cannot open a 'nul' file, Win32-trimmed names, or WSL-created symlinks; treat those per-file errors as skipped rather than failing or truncating the search, and keep symlink-following scans in WSL.
77 lines
3.2 KiB
TypeScript
77 lines
3.2 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { createAccumulator } from './text-search'
|
|
import { RipgrepSearchDiagnostics } from './ripgrep-search-diagnostics'
|
|
|
|
describe('ripgrep search diagnostics', () => {
|
|
it('reports invalid regex diagnostics instead of an empty successful search', () => {
|
|
const diagnostics = new RipgrepSearchDiagnostics()
|
|
diagnostics.append(Buffer.from('regex parse error: unclosed character class'))
|
|
expect(diagnostics.failure(2, null, createAccumulator())?.message).toContain(
|
|
'unclosed character class'
|
|
)
|
|
})
|
|
|
|
it('limits retained diagnostics even for large stderr chunks', () => {
|
|
const diagnostics = new RipgrepSearchDiagnostics()
|
|
diagnostics.append('x'.repeat(100_000))
|
|
diagnostics.append('must not be retained')
|
|
const error = diagnostics.failure(2, null, createAccumulator())
|
|
expect(error?.message).toBe(`Search failed (2): ${'x'.repeat(4096)}`)
|
|
})
|
|
|
|
it('marks permission-error results as incomplete', () => {
|
|
const acc = createAccumulator()
|
|
acc.totalMatches = 1
|
|
expect(new RipgrepSearchDiagnostics().failure(2, null, acc)).toBeNull()
|
|
expect(acc.truncated).toBe(true)
|
|
})
|
|
|
|
it('distinguishes a killed search from intentional truncation', () => {
|
|
const diagnostics = new RipgrepSearchDiagnostics()
|
|
const acc = createAccumulator()
|
|
expect(diagnostics.failure(null, 'SIGTERM', acc)).toBeInstanceOf(Error)
|
|
acc.truncated = true
|
|
expect(diagnostics.failure(null, 'SIGTERM', acc)).toBeNull()
|
|
})
|
|
|
|
it.each([0, 1])('accepts normal exit %i without inventing truncation', (code) => {
|
|
const acc = createAccumulator()
|
|
expect(new RipgrepSearchDiagnostics().failure(code, null, acc)).toBeNull()
|
|
expect(acc.truncated).toBe(false)
|
|
})
|
|
|
|
describe('skippable per-path OS errors', () => {
|
|
const skippable = new Set([1, 1920])
|
|
|
|
it('does not fail or truncate a search whose only errors are unopenable paths', () => {
|
|
const diagnostics = new RipgrepSearchDiagnostics(skippable)
|
|
diagnostics.append('rg: .\\nul: Incorrect function. (os error 1)\r\nrg: .\\li')
|
|
diagnostics.append('nk: The file cannot be accessed by the system. (os error 1920)')
|
|
const acc = createAccumulator()
|
|
acc.totalMatches = 3
|
|
expect(diagnostics.failure(2, null, acc)).toBeNull()
|
|
expect(acc.truncated).toBe(false)
|
|
expect(diagnostics.failure(2, null, createAccumulator())).toBeNull()
|
|
})
|
|
|
|
it('still fails on any other diagnostic', () => {
|
|
const diagnostics = new RipgrepSearchDiagnostics(skippable)
|
|
diagnostics.append('rg: .\\nul: Incorrect function. (os error 1)\n')
|
|
diagnostics.append('rg: ./secret: Access is denied. (os error 5)\n')
|
|
expect(diagnostics.failure(2, null, createAccumulator())).toBeInstanceOf(Error)
|
|
})
|
|
|
|
it('fails when exit 2 left no diagnostic to classify', () => {
|
|
expect(
|
|
new RipgrepSearchDiagnostics(skippable).failure(2, null, createAccumulator())
|
|
).toBeInstanceOf(Error)
|
|
})
|
|
|
|
it('keeps the default policy when no errors are skippable', () => {
|
|
const diagnostics = new RipgrepSearchDiagnostics()
|
|
diagnostics.append('rg: .\\nul: Incorrect function. (os error 1)\n')
|
|
expect(diagnostics.failure(2, null, createAccumulator())).toBeInstanceOf(Error)
|
|
})
|
|
})
|
|
})
|