mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-24 13:01:11 +00:00
fix(update): preserve pnpm and Bun global installs (#107802)
* fix(update): preserve pnpm and bun global installs * fix(update): anchor pnpm updates to invoking install * fix(update): recover skipped pnpm lifecycle * fix(update): fail closed on ambiguous pnpm ownership * fix(update): tolerate pnpm probe warnings * fix(update): bind pnpm installs to project owners * fix(update): isolate pnpm mutations from caller pins * docs(changelog): credit pnpm 11 report Co-authored-by: jincheng-xydt <xu.jincheng@xydigit.com> * chore(changelog): defer release note ownership * fix(update): make package-root fallback explicit * test(update): split pnpm scenario coverage --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
// Shared command runner tests cover update helper command execution and error capture.
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { createGlobalCommandRunner, parseTimeoutMsOrExit } from "./shared.js";
|
||||
import { withTempDir } from "../../test-helpers/temp-dir.js";
|
||||
import { createGlobalCommandRunner, parseTimeoutMsOrExit, resolveUpdateRoot } from "./shared.js";
|
||||
|
||||
const runCommandWithTimeout = vi.hoisted(() => vi.fn());
|
||||
|
||||
@@ -90,4 +93,30 @@ describe("createGlobalCommandRunner", () => {
|
||||
exit.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it.runIf(process.platform !== "win32")(
|
||||
"resolves update ownership from the lexical invocation path",
|
||||
async () => {
|
||||
await withTempDir({ prefix: "openclaw-update-root-" }, async (base) => {
|
||||
const storeRoot = path.join(base, "store", "openclaw");
|
||||
const packageRoot = path.join(base, "global", "v11", "install", "node_modules", "openclaw");
|
||||
await fs.mkdir(path.dirname(packageRoot), { recursive: true });
|
||||
await fs.mkdir(storeRoot, { recursive: true });
|
||||
await fs.writeFile(
|
||||
path.join(storeRoot, "package.json"),
|
||||
JSON.stringify({ name: "openclaw", version: "1.0.0" }),
|
||||
"utf8",
|
||||
);
|
||||
await fs.symlink(storeRoot, packageRoot, "dir");
|
||||
|
||||
const previousArgv = [...process.argv];
|
||||
process.argv[1] = path.join(packageRoot, "openclaw.mjs");
|
||||
try {
|
||||
await expect(resolveUpdateRoot()).resolves.toBe(packageRoot);
|
||||
} finally {
|
||||
process.argv.splice(0, process.argv.length, ...previousArgv);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -173,12 +173,15 @@ export function resolveNodeRunner(): string {
|
||||
|
||||
/** Locate the installed OpenClaw package root that should receive update operations. */
|
||||
export async function resolveUpdateRoot(): Promise<string> {
|
||||
// Preserve the lexical package path from the invoking shim. pnpm 11 package
|
||||
// modules realpath into a shared store, which is not the install owner.
|
||||
const invocationRoot = process.argv[1]
|
||||
? await resolveOpenClawPackageRoot({ cwd: path.dirname(path.resolve(process.argv[1])) })
|
||||
: null;
|
||||
return (
|
||||
(await resolveOpenClawPackageRoot({
|
||||
moduleUrl: import.meta.url,
|
||||
argv1: process.argv[1],
|
||||
cwd: process.cwd(),
|
||||
})) ?? process.cwd()
|
||||
invocationRoot ??
|
||||
(await resolveOpenClawPackageRoot({ moduleUrl: import.meta.url, cwd: process.cwd() })) ??
|
||||
process.cwd()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user