fix: roll back plugin index on config write conflicts

This commit is contained in:
Shakker
2026-04-26 01:08:49 +01:00
parent ca0232ff0e
commit be1d656514
6 changed files with 118 additions and 26 deletions

View File

@@ -6,6 +6,7 @@ import {
loadConfig,
promptYesNo,
refreshPluginRegistry,
replaceConfigFile,
resetPluginsCliTestState,
runPluginsCommand,
runtimeErrors,
@@ -122,6 +123,62 @@ describe("plugins cli uninstall", () => {
});
});
it("restores install records when the config write rejects during uninstall", async () => {
const installRecords = {
alpha: {
source: "path",
sourcePath: ALPHA_INSTALL_PATH,
installPath: ALPHA_INSTALL_PATH,
},
} as const;
const baseConfig = {
plugins: {
entries: {
alpha: { enabled: true },
},
installs: installRecords,
},
} as OpenClawConfig;
const nextConfig = {
plugins: {
entries: {},
installs: {},
},
} as OpenClawConfig;
loadConfig.mockReturnValue(baseConfig);
setInstalledPluginIndexInstallRecords(installRecords);
buildPluginDiagnosticsReport.mockReturnValue({
plugins: [{ id: "alpha", name: "alpha" }],
diagnostics: [],
});
uninstallPlugin.mockResolvedValue({
ok: true,
config: nextConfig,
warnings: [],
actions: {
entry: true,
install: true,
allowlist: false,
loadPath: false,
memorySlot: false,
directory: false,
},
});
replaceConfigFile.mockRejectedValueOnce(new Error("config changed"));
await expect(
runPluginsCommand(["plugins", "uninstall", "alpha", "--force", "--keep-files"]),
).rejects.toThrow("config changed");
expect(writePersistedInstalledPluginIndexInstallRecords).toHaveBeenNthCalledWith(1, {});
expect(writePersistedInstalledPluginIndexInstallRecords).toHaveBeenNthCalledWith(
2,
installRecords,
);
expect(refreshPluginRegistry).not.toHaveBeenCalled();
});
it("exits when uninstall target is not managed by plugin install records", async () => {
loadConfig.mockReturnValue({
plugins: {