fix(#2823): auto-migrate legacy plugin name and warn users at startup
- logLegacyPluginStartupWarning now emits console.warn (visible to user, not just log file) when oh-my-opencode is detected in opencode.json - Auto-migrates opencode.json plugin entry from oh-my-opencode to oh-my-openagent (with backup) - plugin-config.ts: add console.warn when loading legacy config filename - test: 10 tests covering migration, console output, edge cases
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { afterAll, beforeEach, describe, expect, it, mock } from "bun:test"
|
||||
import { afterAll, afterEach, beforeEach, describe, expect, it, mock, spyOn } from "bun:test"
|
||||
import type { LegacyPluginCheckResult } from "./legacy-plugin-warning"
|
||||
|
||||
function createLegacyPluginCheckResult(
|
||||
@@ -8,13 +8,15 @@ function createLegacyPluginCheckResult(
|
||||
hasLegacyEntry: false,
|
||||
hasCanonicalEntry: false,
|
||||
legacyEntries: [],
|
||||
configPath: null,
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
|
||||
const mockCheckForLegacyPluginEntry = mock(() => createLegacyPluginCheckResult())
|
||||
|
||||
const mockLog = mock(() => {})
|
||||
const mockMigrateLegacyPluginEntry = mock(() => false)
|
||||
let consoleWarnSpy: ReturnType<typeof spyOn>
|
||||
|
||||
mock.module("./legacy-plugin-warning", () => ({
|
||||
checkForLegacyPluginEntry: mockCheckForLegacyPluginEntry,
|
||||
@@ -24,6 +26,10 @@ mock.module("./logger", () => ({
|
||||
log: mockLog,
|
||||
}))
|
||||
|
||||
mock.module("./migrate-legacy-plugin-entry", () => ({
|
||||
migrateLegacyPluginEntry: mockMigrateLegacyPluginEntry,
|
||||
}))
|
||||
|
||||
afterAll(() => {
|
||||
mock.restore()
|
||||
})
|
||||
@@ -36,16 +42,24 @@ describe("logLegacyPluginStartupWarning", () => {
|
||||
beforeEach(() => {
|
||||
mockCheckForLegacyPluginEntry.mockReset()
|
||||
mockLog.mockReset()
|
||||
mockMigrateLegacyPluginEntry.mockReset()
|
||||
consoleWarnSpy = spyOn(console, "warn").mockImplementation(() => {})
|
||||
|
||||
mockCheckForLegacyPluginEntry.mockReturnValue(createLegacyPluginCheckResult())
|
||||
mockMigrateLegacyPluginEntry.mockReturnValue(false)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
consoleWarnSpy?.mockRestore()
|
||||
})
|
||||
|
||||
describe("#given OpenCode config contains legacy plugin entries", () => {
|
||||
it("logs the legacy entries with canonical replacements", async () => {
|
||||
it("#then logs the legacy entries with canonical replacements", async () => {
|
||||
//#given
|
||||
mockCheckForLegacyPluginEntry.mockReturnValue(createLegacyPluginCheckResult({
|
||||
hasLegacyEntry: true,
|
||||
legacyEntries: ["oh-my-opencode", "oh-my-opencode@3.13.1"],
|
||||
configPath: "/tmp/opencode.json",
|
||||
}))
|
||||
const { logLegacyPluginStartupWarning } = await importFreshStartupWarningModule()
|
||||
|
||||
@@ -63,10 +77,45 @@ describe("logLegacyPluginStartupWarning", () => {
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
it("#then emits console.warn about the rename", async () => {
|
||||
//#given
|
||||
mockCheckForLegacyPluginEntry.mockReturnValue(createLegacyPluginCheckResult({
|
||||
hasLegacyEntry: true,
|
||||
legacyEntries: ["oh-my-opencode@latest"],
|
||||
configPath: "/tmp/opencode.json",
|
||||
}))
|
||||
const { logLegacyPluginStartupWarning } = await importFreshStartupWarningModule()
|
||||
|
||||
//#when
|
||||
logLegacyPluginStartupWarning()
|
||||
|
||||
//#then
|
||||
expect(consoleWarnSpy).toHaveBeenCalled()
|
||||
const firstCall = consoleWarnSpy.mock.calls[0]?.[0] as string
|
||||
expect(firstCall).toContain("oh-my-opencode")
|
||||
expect(firstCall).toContain("oh-my-openagent")
|
||||
})
|
||||
|
||||
it("#then attempts auto-migration of the opencode.json", async () => {
|
||||
//#given
|
||||
mockCheckForLegacyPluginEntry.mockReturnValue(createLegacyPluginCheckResult({
|
||||
hasLegacyEntry: true,
|
||||
legacyEntries: ["oh-my-opencode"],
|
||||
configPath: "/tmp/opencode.json",
|
||||
}))
|
||||
const { logLegacyPluginStartupWarning } = await importFreshStartupWarningModule()
|
||||
|
||||
//#when
|
||||
logLegacyPluginStartupWarning()
|
||||
|
||||
//#then
|
||||
expect(mockMigrateLegacyPluginEntry).toHaveBeenCalledWith("/tmp/opencode.json")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given OpenCode config uses only canonical plugin entries", () => {
|
||||
it("does not log a startup warning", async () => {
|
||||
it("#then does not log a startup warning", async () => {
|
||||
//#given
|
||||
const { logLegacyPluginStartupWarning } = await importFreshStartupWarningModule()
|
||||
|
||||
@@ -75,6 +124,27 @@ describe("logLegacyPluginStartupWarning", () => {
|
||||
|
||||
//#then
|
||||
expect(mockLog).not.toHaveBeenCalled()
|
||||
expect(consoleWarnSpy).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given migration succeeds", () => {
|
||||
it("#then logs success message to console", async () => {
|
||||
//#given
|
||||
mockCheckForLegacyPluginEntry.mockReturnValue(createLegacyPluginCheckResult({
|
||||
hasLegacyEntry: true,
|
||||
legacyEntries: ["oh-my-opencode@latest"],
|
||||
configPath: "/tmp/opencode.json",
|
||||
}))
|
||||
mockMigrateLegacyPluginEntry.mockReturnValue(true)
|
||||
const { logLegacyPluginStartupWarning } = await importFreshStartupWarningModule()
|
||||
|
||||
//#when
|
||||
logLegacyPluginStartupWarning()
|
||||
|
||||
//#then
|
||||
const calls = consoleWarnSpy.mock.calls.map((c) => c[0] as string)
|
||||
expect(calls.some((c) => c.includes("Auto-migrated"))).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user