Merge pull request #4356 from Yeachan-Heo/fix/issue-3805-auto-tools-path

fix(grep): include OpenCode cache-backed bin in rg path resolution (#3805)
This commit is contained in:
YeonGyu-Kim
2026-05-24 02:07:17 +09:00
committed by GitHub
2 changed files with 61 additions and 1 deletions
+56
View File
@@ -0,0 +1,56 @@
import { afterEach, beforeEach, describe, expect, it } from "bun:test"
import { mkdirSync, rmSync, writeFileSync } from "node:fs"
import { join } from "node:path"
import { tmpdir } from "node:os"
describe("resolveGrepCli OpenCode cache fallback (#3805)", () => {
let tempCache: string
let tempData: string
let originalCache: string | undefined
let originalData: string | undefined
beforeEach(() => {
const stamp = `omo-ripgrep-cli-${process.pid}-${Date.now()}`
tempCache = join(tmpdir(), `${stamp}-cache`)
tempData = join(tmpdir(), `${stamp}-data`)
mkdirSync(tempCache, { recursive: true })
mkdirSync(tempData, { recursive: true })
originalCache = process.env.XDG_CACHE_HOME
originalData = process.env.XDG_DATA_HOME
process.env.XDG_CACHE_HOME = tempCache
process.env.XDG_DATA_HOME = tempData
})
afterEach(() => {
if (originalCache === undefined) delete process.env.XDG_CACHE_HOME
else process.env.XDG_CACHE_HOME = originalCache
if (originalData === undefined) delete process.env.XDG_DATA_HOME
else process.env.XDG_DATA_HOME = originalData
try {
rmSync(tempCache, { recursive: true, force: true })
rmSync(tempData, { recursive: true, force: true })
} catch {
// best-effort cleanup
}
})
it("prefers ~/.cache/opencode/bin/rg over ~/.local/share/opencode/bin/rg", async () => {
const rgName = process.platform === "win32" ? "rg.exe" : "rg"
const cacheBinDir = join(tempCache, "opencode", "bin")
const dataBinDir = join(tempData, "opencode", "bin")
mkdirSync(cacheBinDir, { recursive: true })
mkdirSync(dataBinDir, { recursive: true })
const cacheRg = join(cacheBinDir, rgName)
const dataRg = join(dataBinDir, rgName)
writeFileSync(cacheRg, "")
writeFileSync(dataRg, "")
// Reset the module cache so the singleton cachedCli is fresh.
delete require.cache[require.resolve("./ripgrep-cli")]
const { resolveGrepCli } = await import("./ripgrep-cli")
const resolved = resolveGrepCli()
expect(resolved.backend).toBe("rg")
expect(resolved.path).toBe(cacheRg)
})
})
+5 -1
View File
@@ -2,7 +2,7 @@ import { spawnSync } from "node:child_process"
import { existsSync } from "node:fs"
import { dirname, join } from "node:path"
import { downloadAndInstallRipgrep, getInstalledRipgrepPath } from "../tools/grep/downloader"
import { getDataDir } from "./data-path"
import { getDataDir, getOpenCodeCacheDir } from "./data-path"
import { log } from "./logger"
import { PUBLISHED_PACKAGE_NAME } from "./plugin-identity"
@@ -48,6 +48,10 @@ function getOpenCodeBundledRg(): string | null {
const rgName = isWindows ? "rg.exe" : "rg"
const candidates = [
// #3805: Upstream OpenCode's Global.Path.bin is cache-backed (~/.cache/opencode/bin),
// and its auto-downloaded ripgrep + LSP binaries live there. Probe it first so OMO
// reuses tools OpenCode already installed instead of triggering a duplicate download.
join(getOpenCodeCacheDir(), "bin", rgName),
join(getDataDir(), "opencode", "bin", rgName),
join(execDir, rgName),
join(execDir, "bin", rgName),