fix(doctor): unify version check to use same source as get-local-version (#367)

This commit is contained in:
Sisyphus
2025-12-31 12:11:10 +09:00
committed by GitHub
parent f890abdc11
commit 471cf868ff

View File

@@ -1,76 +1,11 @@
import { existsSync, readFileSync } from "node:fs"
import { homedir } from "node:os"
import { join } from "node:path"
import type { CheckResult, CheckDefinition, VersionCheckInfo } from "../types" import type { CheckResult, CheckDefinition, VersionCheckInfo } from "../types"
import { CHECK_IDS, CHECK_NAMES, PACKAGE_NAME } from "../constants" import { CHECK_IDS, CHECK_NAMES } from "../constants"
import { parseJsonc } from "../../../shared" import {
getCachedVersion,
const OPENCODE_CONFIG_DIR = join(homedir(), ".config", "opencode") getLatestVersion,
const OPENCODE_PACKAGE_JSON = join(OPENCODE_CONFIG_DIR, "package.json") isLocalDevMode,
const OPENCODE_JSON = join(OPENCODE_CONFIG_DIR, "opencode.json") findPluginEntry,
const OPENCODE_JSONC = join(OPENCODE_CONFIG_DIR, "opencode.jsonc") } from "../../../hooks/auto-update-checker/checker"
async function fetchLatestVersion(): Promise<string | null> {
try {
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
signal: AbortSignal.timeout(5000),
})
if (!res.ok) return null
const data = (await res.json()) as { version: string }
return data.version
} catch {
return null
}
}
function getCurrentVersion(): {
version: string | null
isLocalDev: boolean
isPinned: boolean
pinnedVersion: string | null
} {
const configPath = existsSync(OPENCODE_JSONC) ? OPENCODE_JSONC : OPENCODE_JSON
if (!existsSync(configPath)) {
return { version: null, isLocalDev: false, isPinned: false, pinnedVersion: null }
}
try {
const content = readFileSync(configPath, "utf-8")
const config = parseJsonc<{ plugin?: string[] }>(content)
const plugins = config.plugin ?? []
for (const plugin of plugins) {
if (plugin.startsWith("file:") && plugin.includes(PACKAGE_NAME)) {
return { version: "local-dev", isLocalDev: true, isPinned: false, pinnedVersion: null }
}
if (plugin.startsWith(`${PACKAGE_NAME}@`)) {
const pinnedVersion = plugin.split("@")[1]
return { version: pinnedVersion, isLocalDev: false, isPinned: true, pinnedVersion }
}
if (plugin === PACKAGE_NAME) {
if (existsSync(OPENCODE_PACKAGE_JSON)) {
try {
const pkgContent = readFileSync(OPENCODE_PACKAGE_JSON, "utf-8")
const pkg = JSON.parse(pkgContent) as { dependencies?: Record<string, string> }
const depVersion = pkg.dependencies?.[PACKAGE_NAME]
if (depVersion) {
const cleanVersion = depVersion.replace(/^[\^~]/, "")
return { version: cleanVersion, isLocalDev: false, isPinned: false, pinnedVersion: null }
}
} catch {
// intentionally empty - parse errors ignored
}
}
return { version: null, isLocalDev: false, isPinned: false, pinnedVersion: null }
}
}
return { version: null, isLocalDev: false, isPinned: false, pinnedVersion: null }
} catch {
return { version: null, isLocalDev: false, isPinned: false, pinnedVersion: null }
}
}
function compareVersions(current: string, latest: string): boolean { function compareVersions(current: string, latest: string): boolean {
const parseVersion = (v: string): number[] => { const parseVersion = (v: string): number[] => {
@@ -91,22 +26,43 @@ function compareVersions(current: string, latest: string): boolean {
} }
export async function getVersionInfo(): Promise<VersionCheckInfo> { export async function getVersionInfo(): Promise<VersionCheckInfo> {
const current = getCurrentVersion() const cwd = process.cwd()
const latestVersion = await fetchLatestVersion()
if (isLocalDevMode(cwd)) {
return {
currentVersion: "local-dev",
latestVersion: null,
isUpToDate: true,
isLocalDev: true,
isPinned: false,
}
}
const pluginInfo = findPluginEntry(cwd)
if (pluginInfo?.isPinned) {
return {
currentVersion: pluginInfo.pinnedVersion,
latestVersion: null,
isUpToDate: true,
isLocalDev: false,
isPinned: true,
}
}
const currentVersion = getCachedVersion()
const latestVersion = await getLatestVersion()
const isUpToDate = const isUpToDate =
current.isLocalDev || !currentVersion ||
current.isPinned ||
!current.version ||
!latestVersion || !latestVersion ||
compareVersions(current.version, latestVersion) compareVersions(currentVersion, latestVersion)
return { return {
currentVersion: current.version, currentVersion,
latestVersion, latestVersion,
isUpToDate, isUpToDate,
isLocalDev: current.isLocalDev, isLocalDev: false,
isPinned: current.isPinned, isPinned: false,
} }
} }