




















@@ -1,4 +1,5 @@
11import fs from "node:fs/promises";
2+import { tmpdir } from "node:os";
23import path from "node:path";
34import { describe, expect, it, vi } from "vitest";
45import {
@@ -181,29 +182,79 @@ describe("bundled plugin postinstall", () => {
181182expect(spawnSync).not.toHaveBeenCalled();
182183});
183184184-it("prunes OpenClaw compile cache during package postinstall", () => {
185+it("prunes Node versioned compile cache dirs during package postinstall", () => {
186+const configuredBase = path.join("/tmp", "openclaw-cache");
187+const defaultBase = path.join(tmpdir(), "node-compile-cache");
185188const removed: string[] = [];
186-const existsSync = vi.fn((value: string) =>
187-value.endsWith(path.join("openclaw-cache", "openclaw")),
188-);
189+const existsSync = vi.fn((value: string) => value === configuredBase || value === defaultBase);
190+const readdirSync = vi.fn((value: string) => {
191+if (value === configuredBase) {
192+return [
193+{ name: "v22.13.1-x64-efe9a9df-1001", isDirectory: () => true },
194+{ name: "openclaw", isDirectory: () => true },
195+{ name: "README", isDirectory: () => false },
196+];
197+}
198+if (value === defaultBase) {
199+return [{ name: "v24.14.1-x64-efe9a9df-1001", isDirectory: () => true }];
200+}
201+throw new Error(`unexpected readdir: ${value}`);
202+});
189203const rmSync = vi.fn((value: string) => {
190204removed.push(value);
191205});
192206193207pruneOpenClawCompileCache({
194-env: { NODE_COMPILE_CACHE: path.join("/tmp", "openclaw-cache") },
208+env: { NODE_COMPILE_CACHE: configuredBase },
195209 existsSync,
210+ readdirSync,
196211 rmSync,
197212log: { warn: vi.fn() },
198213});
199214200-expect(removed).toEqual([path.join("/tmp", "openclaw-cache", "openclaw")]);
201-expect(rmSync).toHaveBeenCalledWith(path.join("/tmp", "openclaw-cache", "openclaw"), {
202-recursive: true,
203-force: true,
204-maxRetries: 2,
205-retryDelay: 100,
215+expect(removed).toEqual([
216+path.join(configuredBase, "v22.13.1-x64-efe9a9df-1001"),
217+path.join(defaultBase, "v24.14.1-x64-efe9a9df-1001"),
218+]);
219+expect(removed).not.toContain(path.join(configuredBase, "openclaw"));
220+for (const cacheDir of removed) {
221+expect(rmSync).toHaveBeenCalledWith(cacheDir, {
222+recursive: true,
223+force: true,
224+maxRetries: 2,
225+retryDelay: 100,
226+});
227+}
228+});
229+230+it("keeps pruning sibling compile cache dirs after one removal fails", () => {
231+const configuredBase = path.join("/tmp", "openclaw-cache");
232+const attempted: string[] = [];
233+const warn = vi.fn();
234+const firstCacheDir = path.join(configuredBase, "v22.13.1-x64-efe9a9df-1001");
235+const secondCacheDir = path.join(configuredBase, "v22.13.1-x64-efe9a9df-1002");
236+const rmSync = vi.fn((value: string) => {
237+attempted.push(value);
238+if (value === firstCacheDir) {
239+throw new Error("locked");
240+}
241+});
242+243+pruneOpenClawCompileCache({
244+env: { NODE_COMPILE_CACHE: configuredBase },
245+existsSync: vi.fn((value: string) => value === configuredBase),
246+readdirSync: vi.fn(() => [
247+{ name: path.basename(firstCacheDir), isDirectory: () => true },
248+{ name: path.basename(secondCacheDir), isDirectory: () => true },
249+]),
250+ rmSync,
251+log: { warn },
206252});
253+254+expect(attempted).toEqual([firstCacheDir, secondCacheDir]);
255+expect(warn).toHaveBeenCalledWith(
256+"[postinstall] could not prune OpenClaw compile cache: Error: locked",
257+);
207258});
208259209260it("prunes source-checkout bundled plugin node_modules", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。