fix(cli): routed update plugin shorthand

Added the documented update -l path for marketplace plugin upgrades and covered the dispatch contract with update command tests.

Fixes #4304
This commit is contained in:
roboomp
2026-07-02 11:48:42 +00:00
parent 0ea6ea630b
commit 7cb413988f
4 changed files with 63 additions and 9 deletions
+42 -1
View File
@@ -1,20 +1,25 @@
import { afterEach, describe, expect, it, spyOn } from "bun:test";
import { afterEach, describe, expect, it, spyOn, vi } from "bun:test";
import * as nodeFs from "node:fs";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as pluginCli from "@oh-my-pi/pi-coding-agent/cli/plugin-cli";
import * as updateCli from "@oh-my-pi/pi-coding-agent/cli/update-cli";
import {
buildBunInstallArgs,
buildHomebrewUpdateArgs,
buildMiseForceInstallArgs,
buildMiseUpgradeArgs,
parseUpdateArgs,
pruneBunInstallCache,
replaceBinaryForUpdate,
resolveBunGlobalNodeModulesDirFromLocations,
resolveUpdateMethodForTest,
sweepStaleBackups,
} from "@oh-my-pi/pi-coding-agent/cli/update-cli";
import Update from "@oh-my-pi/pi-coding-agent/commands/update";
import { removeWithRetries } from "@oh-my-pi/pi-utils";
import type { CliConfig } from "@oh-my-pi/pi-utils/cli";
const tempDirs: string[] = [];
@@ -25,8 +30,44 @@ async function makeTempDir(): Promise<string> {
}
afterEach(async () => {
vi.restoreAllMocks();
await Promise.all(tempDirs.splice(0).map(dir => removeWithRetries(dir)));
});
const TEST_CONFIG: CliConfig = {
bin: "omp",
version: "0.0.0-test",
commands: new Map(),
};
describe("update command plugin dispatch", () => {
it("routes -l to plugin upgrade instead of the app updater", async () => {
const pluginSpy = spyOn(pluginCli, "runPluginCommand").mockResolvedValue(undefined);
const updateSpy = spyOn(updateCli, "runUpdateCommand").mockResolvedValue(undefined);
const command = new Update(["-l"], TEST_CONFIG);
await command.run();
expect(pluginSpy).toHaveBeenCalledWith({ action: "upgrade", args: [], flags: {} });
expect(updateSpy).not.toHaveBeenCalled();
});
it("keeps normal update flags on the app updater path", async () => {
const pluginSpy = spyOn(pluginCli, "runPluginCommand").mockResolvedValue(undefined);
const updateSpy = spyOn(updateCli, "runUpdateCommand").mockResolvedValue(undefined);
const command = new Update(["--check", "--force"], TEST_CONFIG);
await command.run();
expect(updateSpy).toHaveBeenCalledWith({ force: true, check: true });
expect(pluginSpy).not.toHaveBeenCalled();
});
});
describe("parseUpdateArgs", () => {
it("preserves the legacy plugin update shorthand", () => {
expect(parseUpdateArgs(["update", "-l"])).toEqual({ force: false, check: false, plugins: true });
});
});
describe("update-cli install target detection", () => {
it("uses bun update when prioritized omp is inside bun global bin", () => {
const method = resolveUpdateMethodForTest("/Users/test/.bun/bin/omp", "/Users/test/.bun/bin");