fix(cli): clarify source archive install failures
This commit is contained in:
parent
040c43ae21
commit
c37a92ca6e
35
openclaw.mjs
35
openclaw.mjs
@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import { access } from "node:fs/promises";
|
||||||
import module from "node:module";
|
import module from "node:module";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
@ -59,7 +60,11 @@ const isDirectModuleNotFoundError = (err, specifier) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const message = "message" in err && typeof err.message === "string" ? err.message : "";
|
const message = "message" in err && typeof err.message === "string" ? err.message : "";
|
||||||
return message.includes(fileURLToPath(expectedUrl));
|
const expectedPath = fileURLToPath(expectedUrl);
|
||||||
|
return (
|
||||||
|
message.includes(`Cannot find module '${expectedPath}'`) ||
|
||||||
|
message.includes(`Cannot find module "${expectedPath}"`)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const installProcessWarningFilter = async () => {
|
const installProcessWarningFilter = async () => {
|
||||||
@ -95,10 +100,36 @@ const tryImport = async (specifier) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const exists = async (specifier) => {
|
||||||
|
try {
|
||||||
|
await access(new URL(specifier, import.meta.url));
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildMissingEntryErrorMessage = async () => {
|
||||||
|
const lines = ["openclaw: missing dist/entry.(m)js (build output)."];
|
||||||
|
if (!(await exists("./src/entry.ts"))) {
|
||||||
|
return lines.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.push("This install looks like an unbuilt source tree or GitHub source archive.");
|
||||||
|
lines.push(
|
||||||
|
"Build locally with `pnpm install && pnpm build`, or install a built package instead.",
|
||||||
|
);
|
||||||
|
lines.push(
|
||||||
|
"For pinned GitHub installs, use `npm install -g github:openclaw/openclaw#<ref>` instead of a raw `/archive/<ref>.tar.gz` URL.",
|
||||||
|
);
|
||||||
|
lines.push("For releases, use `npm install -g openclaw@latest`.");
|
||||||
|
return lines.join("\n");
|
||||||
|
};
|
||||||
|
|
||||||
if (await tryImport("./dist/entry.js")) {
|
if (await tryImport("./dist/entry.js")) {
|
||||||
// OK
|
// OK
|
||||||
} else if (await tryImport("./dist/entry.mjs")) {
|
} else if (await tryImport("./dist/entry.mjs")) {
|
||||||
// OK
|
// OK
|
||||||
} else {
|
} else {
|
||||||
throw new Error("openclaw: missing dist/entry.(m)js (build output).");
|
throw new Error(await buildMissingEntryErrorMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,11 @@ async function makeLauncherFixture(fixtureRoots: string[]): Promise<string> {
|
|||||||
return fixtureRoot;
|
return fixtureRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addSourceTreeMarker(fixtureRoot: string): Promise<void> {
|
||||||
|
await fs.mkdir(path.join(fixtureRoot, "src"), { recursive: true });
|
||||||
|
await fs.writeFile(path.join(fixtureRoot, "src", "entry.ts"), "export {};\n", "utf8");
|
||||||
|
}
|
||||||
|
|
||||||
describe("openclaw launcher", () => {
|
describe("openclaw launcher", () => {
|
||||||
const fixtureRoots: string[] = [];
|
const fixtureRoots: string[] = [];
|
||||||
|
|
||||||
@ -55,4 +60,20 @@ describe("openclaw launcher", () => {
|
|||||||
expect(result.status).not.toBe(0);
|
expect(result.status).not.toBe(0);
|
||||||
expect(result.stderr).toContain("missing dist/entry.(m)js");
|
expect(result.stderr).toContain("missing dist/entry.(m)js");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("explains how to recover from an unbuilt source install", async () => {
|
||||||
|
const fixtureRoot = await makeLauncherFixture(fixtureRoots);
|
||||||
|
await addSourceTreeMarker(fixtureRoot);
|
||||||
|
|
||||||
|
const result = spawnSync(process.execPath, [path.join(fixtureRoot, "openclaw.mjs"), "--help"], {
|
||||||
|
cwd: fixtureRoot,
|
||||||
|
encoding: "utf8",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.status).not.toBe(0);
|
||||||
|
expect(result.stderr).toContain("missing dist/entry.(m)js");
|
||||||
|
expect(result.stderr).toContain("unbuilt source tree or GitHub source archive");
|
||||||
|
expect(result.stderr).toContain("pnpm install && pnpm build");
|
||||||
|
expect(result.stderr).toContain("github:openclaw/openclaw#<ref>");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user