fix(build): prune stale bundled plugin node_modules

This commit is contained in:
Ayaan Zaidi
2026-04-08 20:18:08 +05:30
parent e4c7ee5856
commit b28fe1b92f
3 changed files with 106 additions and 6 deletions

View File

@@ -4,6 +4,7 @@ import { describe, expect, it, vi } from "vitest";
import {
createNestedNpmInstallEnv,
discoverBundledPluginRuntimeDeps,
pruneBundledPluginSourceNodeModules,
runBundledPluginPostinstall,
} from "../../scripts/postinstall-bundled-plugins.mjs";
import { createScriptTestHarness } from "./test-helpers.js";
@@ -100,6 +101,37 @@ describe("bundled plugin postinstall", () => {
expect(spawnSync).toHaveBeenCalled();
});
it("prunes source-checkout bundled plugin node_modules", async () => {
const packageRoot = await createTempDirAsync("openclaw-source-checkout-");
const extensionsDir = path.join(packageRoot, "extensions");
await fs.mkdir(path.join(packageRoot, ".git"), { recursive: true });
await fs.mkdir(path.join(packageRoot, "src"), { recursive: true });
await fs.mkdir(extensionsDir, { recursive: true });
await writePluginPackage(extensionsDir, "acpx", {
dependencies: {
acpx: "0.5.2",
},
});
await fs.mkdir(path.join(extensionsDir, "acpx", "node_modules", "acpx"), { recursive: true });
await fs.writeFile(
path.join(extensionsDir, "acpx", "node_modules", "acpx", "package.json"),
JSON.stringify({ name: "acpx", version: "0.4.1" }),
);
const spawnSync = vi.fn();
runBundledPluginPostinstall({
env: { HOME: "/tmp/home" },
extensionsDir,
packageRoot,
spawnSync,
});
await expect(fs.stat(path.join(extensionsDir, "acpx", "node_modules"))).rejects.toMatchObject({
code: "ENOENT",
});
expect(spawnSync).not.toHaveBeenCalled();
});
it("runs nested local installs with sanitized env when the sentinel package is missing", async () => {
const extensionsDir = await createExtensionsDir();
const packageRoot = path.dirname(path.dirname(extensionsDir));
@@ -302,4 +334,24 @@ describe("bundled plugin postinstall", () => {
expectNpmInstallSpawn(spawnSync, packageRoot, ["grammy@1.38.4"]);
});
it("prunes only bundled plugin package node_modules in source checkouts", async () => {
const packageRoot = await createTempDirAsync("openclaw-source-prune-");
const extensionsDir = path.join(packageRoot, "extensions");
await fs.mkdir(path.join(extensionsDir, "acpx", "node_modules"), { recursive: true });
await fs.mkdir(path.join(extensionsDir, "fixtures", "node_modules"), { recursive: true });
await fs.writeFile(
path.join(extensionsDir, "acpx", "package.json"),
JSON.stringify({ name: "@openclaw/acpx" }),
);
pruneBundledPluginSourceNodeModules({ extensionsDir });
await expect(fs.stat(path.join(extensionsDir, "acpx", "node_modules"))).rejects.toMatchObject({
code: "ENOENT",
});
await expect(
fs.stat(path.join(extensionsDir, "fixtures", "node_modules")),
).resolves.toBeTruthy();
});
});