fix(plugins): clean managed git uninstall roots

This commit is contained in:
Vincent Koc
2026-05-02 23:17:40 -07:00
parent cb7b2850e4
commit f249b1c6df
5 changed files with 153 additions and 13 deletions

View File

@@ -18,6 +18,34 @@ function getInstallRecords() {
: (index.installRecords ?? {});
}
function readOpenClawConfig() {
const configPath = path.join(process.env.HOME, ".openclaw", "openclaw.json");
return fs.existsSync(configPath) ? readJson(configPath) : {};
}
function assertPluginRemoved(params) {
const list = readJson(params.listFile);
if ((list.plugins || []).some((entry) => entry.id === params.pluginId)) {
throw new Error(`${params.pluginId} still listed after uninstall`);
}
const installRecords = getInstallRecords();
if (installRecords[params.pluginId]) {
throw new Error(`${params.pluginId} install record still present after uninstall`);
}
const config = readOpenClawConfig();
if (config.plugins?.entries?.[params.pluginId]) {
throw new Error(`${params.pluginId} config entry still present after uninstall`);
}
if ((config.plugins?.allow || []).includes(params.pluginId)) {
throw new Error(`${params.pluginId} allowlist entry still present after uninstall`);
}
if ((config.plugins?.deny || []).includes(params.pluginId)) {
throw new Error(`${params.pluginId} denylist entry still present after uninstall`);
}
}
function recordFixturePluginTrust() {
const pluginId = process.argv[3];
const pluginRoot = process.argv[4];
@@ -272,6 +300,25 @@ function assertGitPlugin() {
throw new Error(`missing git plugin installed dependency: ${dependencyPackagePath}`);
}
assertRealPathInside(installPath, dependencyPackagePath, "git plugin installed dependency");
fs.writeFileSync("/tmp/plugins-git-install-path.txt", installPath, "utf8");
fs.writeFileSync("/tmp/plugins-git-install-parent.txt", path.dirname(installPath), "utf8");
}
function assertGitPluginRemoved() {
const installPath = fs.readFileSync("/tmp/plugins-git-install-path.txt", "utf8").trim();
const installParent = fs.readFileSync("/tmp/plugins-git-install-parent.txt", "utf8").trim();
assertPluginRemoved({
pluginId: "demo-plugin-git",
listFile: "/tmp/plugins-git-uninstalled.json",
});
if (fs.existsSync(installPath)) {
throw new Error(`git managed repo still exists after uninstall: ${installPath}`);
}
if (fs.existsSync(installParent)) {
throw new Error(
`empty git managed install parent still exists after uninstall: ${installParent}`,
);
}
}
function assertRealPathInside(parentPath, childPath, label) {
@@ -407,6 +454,8 @@ function assertNpmPlugin() {
throw new Error(`missing npm plugin installed dependency: ${dependencyPackagePath}`);
}
assertRealPathInside(npmRoot, dependencyPackagePath, "npm plugin installed dependency");
fs.writeFileSync("/tmp/plugins-npm-install-path.txt", installPath, "utf8");
fs.writeFileSync("/tmp/plugins-npm-dependency-path.txt", dependencyPackagePath, "utf8");
}
function assertNpmPluginUpdateUnchanged() {
@@ -414,6 +463,25 @@ function assertNpmPluginUpdateUnchanged() {
assertNpmPlugin();
}
function assertNpmPluginRemoved() {
const installPath = fs.readFileSync("/tmp/plugins-npm-install-path.txt", "utf8").trim();
const dependencyPackagePath = fs
.readFileSync("/tmp/plugins-npm-dependency-path.txt", "utf8")
.trim();
assertPluginRemoved({
pluginId: "demo-plugin-npm",
listFile: "/tmp/plugins-npm-uninstalled.json",
});
if (fs.existsSync(installPath)) {
throw new Error(`npm managed package still exists after uninstall: ${installPath}`);
}
if (fs.existsSync(dependencyPackagePath)) {
throw new Error(
`npm managed dependency still exists after uninstall: ${dependencyPackagePath}`,
);
}
}
function assertMarketplaceUpdated() {
const data = readJson("/tmp/plugins-marketplace-updated.json");
const inspect = readJson("/tmp/plugins-marketplace-updated-inspect.json");
@@ -646,10 +714,12 @@ const commands = {
),
"plugin-npm": assertNpmPlugin,
"plugin-npm-update": assertNpmPluginUpdateUnchanged,
"plugin-npm-removed": assertNpmPluginRemoved,
"bundle-disabled": assertClaudeBundleDisabled,
"bundle-inspect": assertClaudeBundleInspect,
"slash-install": assertSlashInstall,
"plugin-git": assertGitPlugin,
"plugin-git-removed": assertGitPluginRemoved,
"plugin-git-updated": assertGitPluginUpdated,
"marketplace-list": assertMarketplaceList,
"marketplace-installed": assertMarketplaceInstalled,

View File

@@ -87,6 +87,10 @@ node scripts/e2e/lib/plugins/assertions.mjs plugin-npm
node "$OPENCLAW_ENTRY" plugins update demo-plugin-npm >/tmp/plugins-npm-update.log 2>&1
node scripts/e2e/lib/plugins/assertions.mjs plugin-npm-update
run_logged uninstall-npm node "$OPENCLAW_ENTRY" plugins uninstall demo-plugin-npm --force
node "$OPENCLAW_ENTRY" plugins list --json >/tmp/plugins-npm-uninstalled.json
node scripts/e2e/lib/plugins/assertions.mjs plugin-npm-removed
echo "Testing install from git repo and plugin CLI execution..."
git_fixture_root="$(mktemp -d "/tmp/openclaw-plugin-git.XXXXXX")"
git_repo="$git_fixture_root/repo"
@@ -106,6 +110,10 @@ run_logged exec-git-plugin-cli bash -c 'node "$OPENCLAW_ENTRY" demo-git ping >/t
node scripts/e2e/lib/plugins/assertions.mjs plugin-git "$git_repo_url" "$git_ref"
run_logged uninstall-git node "$OPENCLAW_ENTRY" plugins uninstall demo-plugin-git --force
node "$OPENCLAW_ENTRY" plugins list --json >/tmp/plugins-git-uninstalled.json
node scripts/e2e/lib/plugins/assertions.mjs plugin-git-removed
echo "Testing git plugin update from moving ref..."
git_update_fixture_root="$(mktemp -d "/tmp/openclaw-plugin-git-update.XXXXXX")"
git_update_repo="$git_update_fixture_root/repo"