fix(auto-update): match both canonical and legacy plugin names in entry finder
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -4,6 +4,7 @@ import * as fs from "node:fs"
|
|||||||
import * as os from "node:os"
|
import * as os from "node:os"
|
||||||
import * as path from "node:path"
|
import * as path from "node:path"
|
||||||
import { PACKAGE_NAME } from "../constants"
|
import { PACKAGE_NAME } from "../constants"
|
||||||
|
import { LEGACY_PLUGIN_NAME, PLUGIN_NAME } from "../../../shared/plugin-identity"
|
||||||
|
|
||||||
type PluginEntryResult = {
|
type PluginEntryResult = {
|
||||||
entry: string
|
entry: string
|
||||||
@@ -120,6 +121,64 @@ describe("findPluginEntry", () => {
|
|||||||
expect(pluginInfo?.pinnedVersion).toBe("3.5.2")
|
expect(pluginInfo?.pinnedVersion).toBe("3.5.2")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("finds preferred plugin entry", async () => {
|
||||||
|
// #given preferred plugin entry is configured
|
||||||
|
fs.writeFileSync(configPath, JSON.stringify({ plugin: [PLUGIN_NAME] }))
|
||||||
|
|
||||||
|
// #when plugin entry is detected
|
||||||
|
const execution = runFindPluginEntry(temporaryDirectory)
|
||||||
|
|
||||||
|
// #then preferred entry is returned
|
||||||
|
expect(execution.status).toBe(0)
|
||||||
|
const pluginInfo = JSON.parse(execution.stdout.trim()) as PluginEntryResult
|
||||||
|
expect(pluginInfo?.entry).toBe(PLUGIN_NAME)
|
||||||
|
expect(pluginInfo?.isPinned).toBe(false)
|
||||||
|
expect(pluginInfo?.pinnedVersion).toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("finds legacy plugin entry", async () => {
|
||||||
|
// #given legacy plugin entry is configured
|
||||||
|
fs.writeFileSync(configPath, JSON.stringify({ plugin: [LEGACY_PLUGIN_NAME] }))
|
||||||
|
|
||||||
|
// #when plugin entry is detected
|
||||||
|
const execution = runFindPluginEntry(temporaryDirectory)
|
||||||
|
|
||||||
|
// #then legacy entry is returned
|
||||||
|
expect(execution.status).toBe(0)
|
||||||
|
const pluginInfo = JSON.parse(execution.stdout.trim()) as PluginEntryResult
|
||||||
|
expect(pluginInfo?.entry).toBe(LEGACY_PLUGIN_NAME)
|
||||||
|
expect(pluginInfo?.isPinned).toBe(false)
|
||||||
|
expect(pluginInfo?.pinnedVersion).toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("finds preferred plugin entry with pinned version", async () => {
|
||||||
|
// #given preferred plugin entry includes semver version
|
||||||
|
fs.writeFileSync(configPath, JSON.stringify({ plugin: [`${PLUGIN_NAME}@3.15.0`] }))
|
||||||
|
|
||||||
|
// #when plugin entry is detected
|
||||||
|
const execution = runFindPluginEntry(temporaryDirectory)
|
||||||
|
|
||||||
|
// #then preferred versioned entry is returned
|
||||||
|
expect(execution.status).toBe(0)
|
||||||
|
const pluginInfo = JSON.parse(execution.stdout.trim()) as PluginEntryResult
|
||||||
|
expect(pluginInfo?.entry).toBe(`${PLUGIN_NAME}@3.15.0`)
|
||||||
|
expect(pluginInfo?.isPinned).toBe(true)
|
||||||
|
expect(pluginInfo?.pinnedVersion).toBe("3.15.0")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("returns null for unrelated plugin entry", async () => {
|
||||||
|
// #given unrelated plugin entry is configured
|
||||||
|
fs.writeFileSync(configPath, JSON.stringify({ plugin: ["some-other-plugin"] }))
|
||||||
|
|
||||||
|
// #when plugin entry is detected
|
||||||
|
const execution = runFindPluginEntry(temporaryDirectory)
|
||||||
|
|
||||||
|
// #then no matching entry is returned
|
||||||
|
expect(execution.status).toBe(0)
|
||||||
|
const pluginInfo = JSON.parse(execution.stdout.trim()) as PluginEntryResult
|
||||||
|
expect(pluginInfo).toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
test("reads user config from profile dir even when OPENCODE_CONFIG_DIR changes after import", async () => {
|
test("reads user config from profile dir even when OPENCODE_CONFIG_DIR changes after import", async () => {
|
||||||
// #given profile-specific user config after module import
|
// #given profile-specific user config after module import
|
||||||
const profileConfigDir = path.join(temporaryDirectory, "profiles", "today")
|
const profileConfigDir = path.join(temporaryDirectory, "profiles", "today")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { OpencodeConfig } from "../types"
|
|||||||
import { PACKAGE_NAME } from "../constants"
|
import { PACKAGE_NAME } from "../constants"
|
||||||
import { getConfigPaths } from "./config-paths"
|
import { getConfigPaths } from "./config-paths"
|
||||||
import { stripJsonComments } from "./jsonc-strip"
|
import { stripJsonComments } from "./jsonc-strip"
|
||||||
|
import { LEGACY_PLUGIN_NAME, PLUGIN_NAME } from "../../../shared/plugin-identity"
|
||||||
|
|
||||||
export interface PluginEntryInfo {
|
export interface PluginEntryInfo {
|
||||||
entry: string
|
entry: string
|
||||||
@@ -12,6 +13,7 @@ export interface PluginEntryInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const EXACT_SEMVER_REGEX = /^\d+\.\d+\.\d+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/
|
const EXACT_SEMVER_REGEX = /^\d+\.\d+\.\d+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/
|
||||||
|
const MATCH_PLUGIN_NAMES = [PACKAGE_NAME, PLUGIN_NAME, LEGACY_PLUGIN_NAME]
|
||||||
|
|
||||||
export function findPluginEntry(directory: string): PluginEntryInfo | null {
|
export function findPluginEntry(directory: string): PluginEntryInfo | null {
|
||||||
for (const configPath of getConfigPaths(directory)) {
|
for (const configPath of getConfigPaths(directory)) {
|
||||||
@@ -22,13 +24,15 @@ export function findPluginEntry(directory: string): PluginEntryInfo | null {
|
|||||||
const plugins = config.plugin ?? []
|
const plugins = config.plugin ?? []
|
||||||
|
|
||||||
for (const entry of plugins) {
|
for (const entry of plugins) {
|
||||||
if (entry === PACKAGE_NAME) {
|
for (const pluginName of MATCH_PLUGIN_NAMES) {
|
||||||
return { entry, isPinned: false, pinnedVersion: null, configPath }
|
if (entry === pluginName) {
|
||||||
}
|
return { entry, isPinned: false, pinnedVersion: null, configPath }
|
||||||
if (entry.startsWith(`${PACKAGE_NAME}@`)) {
|
}
|
||||||
const pinnedVersion = entry.slice(PACKAGE_NAME.length + 1)
|
if (entry.startsWith(`${pluginName}@`)) {
|
||||||
const isPinned = EXACT_SEMVER_REGEX.test(pinnedVersion.trim())
|
const pinnedVersion = entry.slice(pluginName.length + 1)
|
||||||
return { entry, isPinned, pinnedVersion, configPath }
|
const isPinned = EXACT_SEMVER_REGEX.test(pinnedVersion.trim())
|
||||||
|
return { entry, isPinned, pinnedVersion, configPath }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
Reference in New Issue
Block a user