mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
fix(plugins): stop tracking runtime deps manifests
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -152,3 +152,7 @@ test/fixtures/openclaw-vitest-unit-report.json
|
||||
analysis/
|
||||
.artifacts/qa-e2e/
|
||||
extensions/qa-lab/web/dist/
|
||||
|
||||
# Generated bundled plugin runtime dependency manifests
|
||||
extensions/**/.openclaw-runtime-deps.json
|
||||
extensions/**/.openclaw-runtime-deps-stamp.json
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"specs": [
|
||||
"@anthropic-ai/sdk@0.90.0",
|
||||
"@aws/bedrock-token-generator@^1.1.0",
|
||||
"@mariozechner/pi-ai@0.69.0"
|
||||
]
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"specs": [
|
||||
"@aws-sdk/client-bedrock-runtime@3.1033.0",
|
||||
"@aws-sdk/client-bedrock@3.1033.0",
|
||||
"@aws-sdk/credential-provider-node@3.972.33"
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["@mariozechner/pi-ai@0.69.0"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["typebox@1.1.28"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["@mariozechner/pi-coding-agent@0.69.0", "ws@^8.20.0", "zod@^4.3.6"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["typebox@1.1.28"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["@mariozechner/pi-ai@0.69.0"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["@clack/prompts@^1.2.0", "@mariozechner/pi-ai@0.69.0"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["@google/genai@^1.50.1", "@mariozechner/pi-ai@0.69.0"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["@mariozechner/pi-ai@0.69.0"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["@mariozechner/pi-ai@0.69.0"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["ws@^8.20.0"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["@mariozechner/pi-ai@0.69.0", "typebox@1.1.28"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["@mariozechner/pi-ai@0.69.0", "ws@^8.20.0"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["typebox@1.1.28"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"specs": ["@mariozechner/pi-ai@0.69.0", "typebox@1.1.28", "ws@^8.20.0"]
|
||||
}
|
||||
@@ -575,14 +575,21 @@ describe("ensureBundledPluginRuntimeDeps", () => {
|
||||
]);
|
||||
expect(installRoot).toContain(stageDir);
|
||||
expect(installRoot).not.toBe(pluginRoot);
|
||||
expect(
|
||||
JSON.parse(fs.readFileSync(path.join(installRoot, ".openclaw-runtime-deps.json"), "utf8")),
|
||||
).toEqual({ specs: ["tokenjuice@0.6.1"] });
|
||||
});
|
||||
|
||||
it("keeps source-checkout bundled runtime deps in the plugin root by default", () => {
|
||||
it("keeps source-checkout bundled runtime deps in the plugin root without manifest churn", () => {
|
||||
const packageRoot = makeTempDir();
|
||||
fs.mkdirSync(path.join(packageRoot, ".git"), { recursive: true });
|
||||
fs.mkdirSync(path.join(packageRoot, "src"), { recursive: true });
|
||||
const pluginRoot = path.join(packageRoot, "extensions", "tokenjuice");
|
||||
fs.mkdirSync(pluginRoot, { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(pluginRoot, ".openclaw-runtime-deps.json"),
|
||||
JSON.stringify({ specs: ["stale@9.9.9"] }),
|
||||
);
|
||||
fs.writeFileSync(
|
||||
path.join(pluginRoot, "package.json"),
|
||||
JSON.stringify({
|
||||
@@ -617,6 +624,43 @@ describe("ensureBundledPluginRuntimeDeps", () => {
|
||||
},
|
||||
]);
|
||||
expect(resolveBundledRuntimeDependencyInstallRoot(pluginRoot, { env: {} })).toBe(pluginRoot);
|
||||
expect(fs.existsSync(path.join(pluginRoot, ".openclaw-runtime-deps.json"))).toBe(false);
|
||||
});
|
||||
|
||||
it("removes stale source-checkout manifests even when runtime deps are present", () => {
|
||||
const packageRoot = makeTempDir();
|
||||
fs.mkdirSync(path.join(packageRoot, ".git"), { recursive: true });
|
||||
fs.mkdirSync(path.join(packageRoot, "src"), { recursive: true });
|
||||
const pluginRoot = path.join(packageRoot, "extensions", "tokenjuice");
|
||||
fs.mkdirSync(path.join(pluginRoot, "node_modules", "tokenjuice"), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(pluginRoot, "package.json"),
|
||||
JSON.stringify({
|
||||
dependencies: {
|
||||
tokenjuice: "0.6.1",
|
||||
},
|
||||
}),
|
||||
);
|
||||
fs.writeFileSync(
|
||||
path.join(pluginRoot, "node_modules", "tokenjuice", "package.json"),
|
||||
JSON.stringify({ name: "tokenjuice", version: "0.6.1" }),
|
||||
);
|
||||
fs.writeFileSync(
|
||||
path.join(pluginRoot, ".openclaw-runtime-deps.json"),
|
||||
JSON.stringify({ specs: ["stale@9.9.9"] }),
|
||||
);
|
||||
|
||||
const result = ensureBundledPluginRuntimeDeps({
|
||||
env: {},
|
||||
installDeps: () => {
|
||||
throw new Error("present source-checkout runtime deps should not reinstall");
|
||||
},
|
||||
pluginId: "tokenjuice",
|
||||
pluginRoot,
|
||||
});
|
||||
|
||||
expect(result).toEqual({ installedSpecs: [], retainSpecs: [] });
|
||||
expect(fs.existsSync(path.join(pluginRoot, ".openclaw-runtime-deps.json"))).toBe(false);
|
||||
});
|
||||
|
||||
it("treats Docker build source trees without .git as source checkouts", () => {
|
||||
|
||||
@@ -263,6 +263,20 @@ function writeRetainedRuntimeDepsManifest(installRoot: string, specs: readonly s
|
||||
);
|
||||
}
|
||||
|
||||
function removeRetainedRuntimeDepsManifest(installRoot: string): void {
|
||||
fs.rmSync(path.join(installRoot, RETAINED_RUNTIME_DEPS_MANIFEST), { force: true });
|
||||
}
|
||||
|
||||
function shouldPersistRetainedRuntimeDepsManifest(params: {
|
||||
pluginRoot: string;
|
||||
installRoot: string;
|
||||
}): boolean {
|
||||
if (path.resolve(params.installRoot) !== path.resolve(params.pluginRoot)) {
|
||||
return true;
|
||||
}
|
||||
return !resolveSourceCheckoutPackageRoot(params.pluginRoot);
|
||||
}
|
||||
|
||||
export function isWritableDirectory(dir: string): boolean {
|
||||
let probeDir: string | null = null;
|
||||
try {
|
||||
@@ -873,6 +887,13 @@ export function ensureBundledPluginRuntimeDeps(params: {
|
||||
const installRoot = resolveBundledRuntimeDependencyInstallRoot(params.pluginRoot, {
|
||||
env: params.env,
|
||||
});
|
||||
const persistRetainedManifest = shouldPersistRetainedRuntimeDepsManifest({
|
||||
pluginRoot: params.pluginRoot,
|
||||
installRoot,
|
||||
});
|
||||
if (!persistRetainedManifest) {
|
||||
removeRetainedRuntimeDepsManifest(installRoot);
|
||||
}
|
||||
const dependencySpecs = deps
|
||||
.map((dep) => `${dep.name}@${dep.version}`)
|
||||
.toSorted((left, right) => left.localeCompare(right));
|
||||
@@ -883,7 +904,9 @@ export function ensureBundledPluginRuntimeDeps(params: {
|
||||
if (missingSpecs.length === 0) {
|
||||
return { installedSpecs: [], retainSpecs: [] };
|
||||
}
|
||||
const retainedManifestSpecs = readRetainedRuntimeDepsManifest(installRoot);
|
||||
const retainedManifestSpecs = persistRetainedManifest
|
||||
? readRetainedRuntimeDepsManifest(installRoot)
|
||||
: [];
|
||||
const installSpecs = [
|
||||
...new Set([...(params.retainSpecs ?? []), ...retainedManifestSpecs, ...dependencySpecs]),
|
||||
].toSorted((left, right) => left.localeCompare(right));
|
||||
@@ -918,7 +941,9 @@ export function ensureBundledPluginRuntimeDeps(params: {
|
||||
env: params.env,
|
||||
}));
|
||||
install({ installRoot, installExecutionRoot, missingSpecs, installSpecs });
|
||||
writeRetainedRuntimeDepsManifest(installRoot, installSpecs);
|
||||
if (persistRetainedManifest) {
|
||||
writeRetainedRuntimeDepsManifest(installRoot, installSpecs);
|
||||
}
|
||||
storeSourceCheckoutRuntimeDepsCache({ cacheDir, installRoot });
|
||||
return { installedSpecs: missingSpecs, retainSpecs: installSpecs };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user