refactor: migrate file/ripgrep.ts from Bun.file()/Bun.write() to Filesystem module (#14159)
This commit is contained in:
@@ -13,6 +13,7 @@ import { Installation } from "../../installation"
|
||||
import path from "path"
|
||||
import { Global } from "../../global"
|
||||
import { modify, applyEdits } from "jsonc-parser"
|
||||
import { Filesystem } from "../../util/filesystem"
|
||||
import { Bus } from "../../bus"
|
||||
|
||||
function getAuthStatusIcon(status: MCP.AuthStatus): string {
|
||||
@@ -388,7 +389,7 @@ async function resolveConfigPath(baseDir: string, global = false) {
|
||||
}
|
||||
|
||||
for (const candidate of candidates) {
|
||||
if (await Bun.file(candidate).exists()) {
|
||||
if (await Filesystem.exists(candidate)) {
|
||||
return candidate
|
||||
}
|
||||
}
|
||||
@@ -398,11 +399,9 @@ async function resolveConfigPath(baseDir: string, global = false) {
|
||||
}
|
||||
|
||||
async function addMcpToConfig(name: string, mcpConfig: Config.Mcp, configPath: string) {
|
||||
const file = Bun.file(configPath)
|
||||
|
||||
let text = "{}"
|
||||
if (await file.exists()) {
|
||||
text = await file.text()
|
||||
if (await Filesystem.exists(configPath)) {
|
||||
text = await Filesystem.readText(configPath)
|
||||
}
|
||||
|
||||
// Use jsonc-parser to modify while preserving comments
|
||||
@@ -411,7 +410,7 @@ async function addMcpToConfig(name: string, mcpConfig: Config.Mcp, configPath: s
|
||||
})
|
||||
const result = applyEdits(text, edits)
|
||||
|
||||
await Bun.write(configPath, result)
|
||||
await Filesystem.write(configPath, result)
|
||||
|
||||
return configPath
|
||||
}
|
||||
|
||||
@@ -255,19 +255,20 @@ export namespace Config {
|
||||
const pkg = path.join(dir, "package.json")
|
||||
const targetVersion = Installation.isLocal() ? "*" : Installation.VERSION
|
||||
|
||||
const json = await Bun.file(pkg)
|
||||
.json()
|
||||
.catch(() => ({}))
|
||||
const json = await Filesystem.readJson<{ dependencies?: Record<string, string> }>(pkg).catch(() => ({
|
||||
dependencies: {},
|
||||
}))
|
||||
json.dependencies = {
|
||||
...json.dependencies,
|
||||
"@opencode-ai/plugin": targetVersion,
|
||||
}
|
||||
await Bun.write(pkg, JSON.stringify(json, null, 2))
|
||||
await Filesystem.writeJson(pkg, json)
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000))
|
||||
|
||||
const gitignore = path.join(dir, ".gitignore")
|
||||
const hasGitIgnore = await Bun.file(gitignore).exists()
|
||||
if (!hasGitIgnore) await Bun.write(gitignore, ["node_modules", "package.json", "bun.lock", ".gitignore"].join("\n"))
|
||||
const hasGitIgnore = await Filesystem.exists(gitignore)
|
||||
if (!hasGitIgnore)
|
||||
await Filesystem.write(gitignore, ["node_modules", "package.json", "bun.lock", ".gitignore"].join("\n"))
|
||||
|
||||
// Install any additional dependencies defined in the package.json
|
||||
// This allows local plugins and custom tools to use external packages
|
||||
@@ -303,11 +304,10 @@ export namespace Config {
|
||||
if (!existsSync(nodeModules)) return true
|
||||
|
||||
const pkg = path.join(dir, "package.json")
|
||||
const pkgFile = Bun.file(pkg)
|
||||
const pkgExists = await pkgFile.exists()
|
||||
const pkgExists = await Filesystem.exists(pkg)
|
||||
if (!pkgExists) return true
|
||||
|
||||
const parsed = await pkgFile.json().catch(() => null)
|
||||
const parsed = await Filesystem.readJson<{ dependencies?: Record<string, string> }>(pkg).catch(() => null)
|
||||
const dependencies = parsed?.dependencies ?? {}
|
||||
const depVersion = dependencies["@opencode-ai/plugin"]
|
||||
if (!depVersion) return true
|
||||
@@ -1220,7 +1220,7 @@ export namespace Config {
|
||||
if (provider && model) result.model = `${provider}/${model}`
|
||||
result["$schema"] = "https://opencode.ai/config.json"
|
||||
result = mergeDeep(result, rest)
|
||||
await Bun.write(path.join(Global.Path.config, "config.json"), JSON.stringify(result, null, 2))
|
||||
await Filesystem.writeJson(path.join(Global.Path.config, "config.json"), result)
|
||||
await fs.unlink(legacy)
|
||||
})
|
||||
.catch(() => {})
|
||||
@@ -1231,12 +1231,10 @@ export namespace Config {
|
||||
|
||||
async function loadFile(filepath: string): Promise<Info> {
|
||||
log.info("loading", { path: filepath })
|
||||
let text = await Bun.file(filepath)
|
||||
.text()
|
||||
.catch((err) => {
|
||||
if (err.code === "ENOENT") return
|
||||
throw new JsonError({ path: filepath }, { cause: err })
|
||||
})
|
||||
let text = await Filesystem.readText(filepath).catch((err: any) => {
|
||||
if (err.code === "ENOENT") return
|
||||
throw new JsonError({ path: filepath }, { cause: err })
|
||||
})
|
||||
if (!text) return {}
|
||||
return load(text, filepath)
|
||||
}
|
||||
@@ -1263,21 +1261,19 @@ export namespace Config {
|
||||
}
|
||||
const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(configDir, filePath)
|
||||
const fileContent = (
|
||||
await Bun.file(resolvedPath)
|
||||
.text()
|
||||
.catch((error) => {
|
||||
const errMsg = `bad file reference: "${match}"`
|
||||
if (error.code === "ENOENT") {
|
||||
throw new InvalidError(
|
||||
{
|
||||
path: configFilepath,
|
||||
message: errMsg + ` ${resolvedPath} does not exist`,
|
||||
},
|
||||
{ cause: error },
|
||||
)
|
||||
}
|
||||
throw new InvalidError({ path: configFilepath, message: errMsg }, { cause: error })
|
||||
})
|
||||
await Filesystem.readText(resolvedPath).catch((error: any) => {
|
||||
const errMsg = `bad file reference: "${match}"`
|
||||
if (error.code === "ENOENT") {
|
||||
throw new InvalidError(
|
||||
{
|
||||
path: configFilepath,
|
||||
message: errMsg + ` ${resolvedPath} does not exist`,
|
||||
},
|
||||
{ cause: error },
|
||||
)
|
||||
}
|
||||
throw new InvalidError({ path: configFilepath, message: errMsg }, { cause: error })
|
||||
})
|
||||
).trim()
|
||||
// escape newlines/quotes, strip outer quotes
|
||||
text = text.replace(match, () => JSON.stringify(fileContent).slice(1, -1))
|
||||
@@ -1314,7 +1310,7 @@ export namespace Config {
|
||||
parsed.data.$schema = "https://opencode.ai/config.json"
|
||||
// Write the $schema to the original text to preserve variables like {env:VAR}
|
||||
const updated = original.replace(/^\s*\{/, '{\n "$schema": "https://opencode.ai/config.json",')
|
||||
await Bun.write(configFilepath, updated).catch(() => {})
|
||||
await Filesystem.write(configFilepath, updated).catch(() => {})
|
||||
}
|
||||
const data = parsed.data
|
||||
if (data.plugin) {
|
||||
@@ -1370,7 +1366,7 @@ export namespace Config {
|
||||
export async function update(config: Info) {
|
||||
const filepath = path.join(Instance.directory, "config.json")
|
||||
const existing = await loadFile(filepath)
|
||||
await Bun.write(filepath, JSON.stringify(mergeDeep(existing, config), null, 2))
|
||||
await Filesystem.writeJson(filepath, mergeDeep(existing, config))
|
||||
await Instance.dispose()
|
||||
}
|
||||
|
||||
@@ -1441,24 +1437,22 @@ export namespace Config {
|
||||
|
||||
export async function updateGlobal(config: Info) {
|
||||
const filepath = globalConfigFile()
|
||||
const before = await Bun.file(filepath)
|
||||
.text()
|
||||
.catch((err) => {
|
||||
if (err.code === "ENOENT") return "{}"
|
||||
throw new JsonError({ path: filepath }, { cause: err })
|
||||
})
|
||||
const before = await Filesystem.readText(filepath).catch((err: any) => {
|
||||
if (err.code === "ENOENT") return "{}"
|
||||
throw new JsonError({ path: filepath }, { cause: err })
|
||||
})
|
||||
|
||||
const next = await (async () => {
|
||||
if (!filepath.endsWith(".jsonc")) {
|
||||
const existing = parseConfig(before, filepath)
|
||||
const merged = mergeDeep(existing, config)
|
||||
await Bun.write(filepath, JSON.stringify(merged, null, 2))
|
||||
await Filesystem.writeJson(filepath, merged)
|
||||
return merged
|
||||
}
|
||||
|
||||
const updated = patchJsonc(before, config)
|
||||
const merged = parseConfig(updated, filepath)
|
||||
await Bun.write(filepath, updated)
|
||||
await Filesystem.write(filepath, updated)
|
||||
return merged
|
||||
})()
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import z from "zod"
|
||||
import { NamedError } from "@opencode-ai/util/error"
|
||||
import { lazy } from "../util/lazy"
|
||||
import { $ } from "bun"
|
||||
import { Filesystem } from "../util/filesystem"
|
||||
|
||||
import { ZipReader, BlobReader, BlobWriter } from "@zip.js/zip.js"
|
||||
import { Log } from "@/util/log"
|
||||
@@ -131,8 +132,7 @@ export namespace Ripgrep {
|
||||
}
|
||||
const filepath = path.join(Global.Path.bin, "rg" + (process.platform === "win32" ? ".exe" : ""))
|
||||
|
||||
const file = Bun.file(filepath)
|
||||
if (!(await file.exists())) {
|
||||
if (!(await Filesystem.exists(filepath))) {
|
||||
const platformKey = `${process.arch}-${process.platform}` as keyof typeof PLATFORM
|
||||
const config = PLATFORM[platformKey]
|
||||
if (!config) throw new UnsupportedPlatformError({ platform: platformKey })
|
||||
@@ -144,9 +144,9 @@ export namespace Ripgrep {
|
||||
const response = await fetch(url)
|
||||
if (!response.ok) throw new DownloadFailedError({ url, status: response.status })
|
||||
|
||||
const buffer = await response.arrayBuffer()
|
||||
const arrayBuffer = await response.arrayBuffer()
|
||||
const archivePath = path.join(Global.Path.bin, filename)
|
||||
await Bun.write(archivePath, buffer)
|
||||
await Filesystem.write(archivePath, Buffer.from(arrayBuffer))
|
||||
if (config.extension === "tar.gz") {
|
||||
const args = ["tar", "-xzf", archivePath, "--strip-components=1"]
|
||||
|
||||
@@ -166,7 +166,7 @@ export namespace Ripgrep {
|
||||
})
|
||||
}
|
||||
if (config.extension === "zip") {
|
||||
const zipFileReader = new ZipReader(new BlobReader(new Blob([await Bun.file(archivePath).arrayBuffer()])))
|
||||
const zipFileReader = new ZipReader(new BlobReader(new Blob([arrayBuffer])))
|
||||
const entries = await zipFileReader.getEntries()
|
||||
let rgEntry: any
|
||||
for (const entry of entries) {
|
||||
@@ -190,7 +190,7 @@ export namespace Ripgrep {
|
||||
stderr: "Failed to extract rg.exe from zip archive",
|
||||
})
|
||||
}
|
||||
await Bun.write(filepath, await rgBlob.arrayBuffer())
|
||||
await Filesystem.write(filepath, Buffer.from(await rgBlob.arrayBuffer()))
|
||||
await zipFileReader.close()
|
||||
}
|
||||
await fs.unlink(archivePath)
|
||||
|
||||
Reference in New Issue
Block a user