fix(core): plugins are always reinstalled (#9675)

This commit is contained in:
Filip
2026-02-03 07:47:52 +01:00
committed by GitHub
parent 3f07dffbb0
commit d116c227e0
4 changed files with 112 additions and 37 deletions

View File

@@ -6,6 +6,7 @@ import { Filesystem } from "../util/filesystem"
import { NamedError } from "@opencode-ai/util/error"
import { readableStreamToText } from "bun"
import { Lock } from "../util/lock"
import { PackageRegistry } from "./registry"
export namespace BunProc {
const log = Log.create({ service: "bun" })
@@ -73,7 +74,17 @@ export namespace BunProc {
const dependencies = parsed.dependencies ?? {}
if (!parsed.dependencies) parsed.dependencies = dependencies
const modExists = await Filesystem.exists(mod)
if (dependencies[pkg] === version && modExists) return mod
const cachedVersion = dependencies[pkg]
if (!modExists || !cachedVersion) {
// continue to install
} else if (version !== "latest" && cachedVersion === version) {
return mod
} else if (version === "latest") {
const isOutdated = await PackageRegistry.isOutdated(pkg, cachedVersion, Global.Path.cache)
if (!isOutdated) return mod
log.info("Cached version is outdated, proceeding with install", { pkg, cachedVersion })
}
const proxied = !!(
process.env.HTTP_PROXY ||

View File

@@ -0,0 +1,48 @@
import { readableStreamToText, semver } from "bun"
import { Log } from "../util/log"
export namespace PackageRegistry {
const log = Log.create({ service: "bun" })
function which() {
return process.execPath
}
export async function info(pkg: string, field: string, cwd?: string): Promise<string | null> {
const result = Bun.spawn([which(), "info", pkg, field], {
cwd,
stdout: "pipe",
stderr: "pipe",
env: {
...process.env,
BUN_BE_BUN: "1",
},
})
const code = await result.exited
const stdout = result.stdout ? await readableStreamToText(result.stdout) : ""
const stderr = result.stderr ? await readableStreamToText(result.stderr) : ""
if (code !== 0) {
log.warn("bun info failed", { pkg, field, code, stderr })
return null
}
const value = stdout.trim()
if (!value) return null
return value
}
export async function isOutdated(pkg: string, cachedVersion: string, cwd?: string): Promise<boolean> {
const latestVersion = await info(pkg, "version", cwd)
if (!latestVersion) {
log.warn("Failed to resolve latest version, using cached", { pkg, cachedVersion })
return false
}
const isRange = /[\s^~*xX<>|=]/.test(cachedVersion)
if (isRange) return !semver.satisfies(latestVersion, cachedVersion)
return semver.order(cachedVersion, latestVersion) === -1
}
}