mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 11:00:42 +00:00
fix(plugins): anchor runtime dependency installs
This commit is contained in:
@@ -117,6 +117,9 @@ Docs: https://docs.openclaw.ai
|
||||
- Plugins/startup: remove ownerless bundled runtime-dependency install locks
|
||||
after a short grace window and include lock owner details when startup times
|
||||
out waiting for a plugin runtime-deps lock.
|
||||
- Plugins/install: anchor bundled runtime-dependency npm installs with an
|
||||
OpenClaw-owned package manifest so Linux updates cannot accidentally write to
|
||||
a parent `$HOME/node_modules` tree. Fixes #71730.
|
||||
- Live tests/voice: accept common STT variants for OpenClaw and ElevenLabs
|
||||
brand names so provider smoke tests fail on real regressions rather than
|
||||
equivalent transcripts.
|
||||
|
||||
@@ -222,6 +222,44 @@ describe("installBundledRuntimeDeps", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("anchors non-isolated external install roots with a package manifest", () => {
|
||||
const parentRoot = makeTempDir();
|
||||
const installRoot = path.join(parentRoot, ".openclaw", "plugin-runtime-deps", "openclaw-test");
|
||||
fs.mkdirSync(path.join(parentRoot, "node_modules", "@grammyjs"), { recursive: true });
|
||||
spawnSyncMock.mockImplementation((_command, _args, options) => {
|
||||
const cwd = String(options?.cwd ?? "");
|
||||
expect(cwd).toBe(installRoot);
|
||||
expect(JSON.parse(fs.readFileSync(path.join(cwd, "package.json"), "utf8"))).toEqual({
|
||||
name: "openclaw-runtime-deps-install",
|
||||
private: true,
|
||||
});
|
||||
return {
|
||||
pid: 123,
|
||||
output: [],
|
||||
stdout: "",
|
||||
stderr: "",
|
||||
signal: null,
|
||||
status: 0,
|
||||
};
|
||||
});
|
||||
|
||||
installBundledRuntimeDeps({
|
||||
installRoot,
|
||||
missingSpecs: ["@grammyjs/runner@^2.0.3"],
|
||||
env: {
|
||||
HOME: parentRoot,
|
||||
},
|
||||
});
|
||||
|
||||
expect(spawnSyncMock).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
expect.any(Array),
|
||||
expect.objectContaining({
|
||||
cwd: installRoot,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("uses an isolated execution root and copies node_modules back when requested", () => {
|
||||
const installRoot = makeTempDir();
|
||||
const installExecutionRoot = makeTempDir();
|
||||
|
||||
@@ -1154,14 +1154,17 @@ function shouldCleanBundledRuntimeDepsInstallExecutionRoot(params: {
|
||||
return installExecutionRoot.startsWith(`${installRoot}${path.sep}`);
|
||||
}
|
||||
|
||||
function writeBundledRuntimeDepsInstallManifest(installExecutionRoot: string): void {
|
||||
function ensureNpmInstallExecutionManifest(installExecutionRoot: string): void {
|
||||
const manifestPath = path.join(installExecutionRoot, "package.json");
|
||||
if (fs.existsSync(manifestPath)) {
|
||||
return;
|
||||
}
|
||||
fs.writeFileSync(
|
||||
path.join(installExecutionRoot, "package.json"),
|
||||
manifestPath,
|
||||
`${JSON.stringify({ name: "openclaw-runtime-deps-install", private: true }, null, 2)}\n`,
|
||||
"utf8",
|
||||
);
|
||||
}
|
||||
|
||||
export function installBundledRuntimeDeps(params: {
|
||||
installRoot: string;
|
||||
installExecutionRoot?: string;
|
||||
@@ -1184,7 +1187,7 @@ export function installBundledRuntimeDeps(params: {
|
||||
// doctor repair path installs directly in the external stage dir; without a
|
||||
// manifest, npm can honor a user's global prefix config and write under
|
||||
// $HOME/node_modules instead of our managed stage.
|
||||
writeBundledRuntimeDepsInstallManifest(installExecutionRoot);
|
||||
ensureNpmInstallExecutionManifest(installExecutionRoot);
|
||||
const installEnv = createBundledRuntimeDepsInstallEnv(params.env, {
|
||||
cacheDir: path.join(installExecutionRoot, ".openclaw-npm-cache"),
|
||||
});
|
||||
|
||||
@@ -176,6 +176,7 @@ describe("resolveInstalledPluginProviderContributionIds", () => {
|
||||
resolveInstalledPluginProviderContributionIds({
|
||||
candidates: [candidate],
|
||||
env: hermeticEnv(),
|
||||
preferPersisted: false,
|
||||
}),
|
||||
).toEqual(["demo", "demo-alias"]);
|
||||
});
|
||||
@@ -197,6 +198,7 @@ describe("resolveInstalledPluginProviderContributionIds", () => {
|
||||
},
|
||||
},
|
||||
env: hermeticEnv(),
|
||||
preferPersisted: false,
|
||||
};
|
||||
|
||||
expect(resolveInstalledPluginProviderContributionIds(params)).toEqual([]);
|
||||
|
||||
Reference in New Issue
Block a user