























@@ -2,6 +2,7 @@ import { spawn } from "node:child_process";
22import fs from "node:fs";
33import { createRequire } from "node:module";
44import path from "node:path";
5+import { fileURLToPath } from "node:url";
56import { isUiTestTarget, isUnitUiTestTarget } from "../test/vitest/vitest.ui-paths.mjs";
67import { resolveLocalVitestEnv } from "./lib/vitest-local-scheduling.mjs";
78import { spawnPnpmRunner } from "./pnpm-runner.mjs";
@@ -73,6 +74,7 @@ const VITEST_DOTTED_OPTIONS_WITH_VALUE_PREFIXES = [
7374"--typecheck.",
7475];
7576const require = createRequire(import.meta.url);
77+const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
76787779function isTruthyEnvValue(value) {
7880return TRUTHY_ENV_VALUES.has(value?.trim().toLowerCase() ?? "");
@@ -91,8 +93,43 @@ export function resolveVitestNodeArgs(env = process.env) {
9193return ["--no-maglev"];
9294}
939594-export function resolveVitestCliEntry() {
95-const vitestPackageJson = require.resolve("vitest/package.json");
96+function isMissingVitestResolveError(error) {
97+return (
98+error instanceof Error &&
99+error.code === "MODULE_NOT_FOUND" &&
100+error.message.includes("vitest/package.json")
101+);
102+}
103+104+export function resolveMissingVitestDependencyMessage(baseDir = repoRoot, fsImpl = fs) {
105+const hasNodeModules = fsImpl.existsSync(path.join(baseDir, "node_modules"));
106+const reason = hasNodeModules
107+ ? "[vitest] Vitest is not installed in node_modules."
108+ : "[vitest] node_modules is missing; Vitest cannot be resolved.";
109+return [
110+reason,
111+"Install dependencies before running scripts/run-vitest.mjs:",
112+" pnpm install --frozen-lockfile",
113+"For raw Crabbox/AWS macOS source syncs, hydrate or install dependencies before this runner.",
114+].join("\n");
115+}
116+117+export function resolveVitestCliEntry({
118+ baseDir = repoRoot,
119+ fsImpl = fs,
120+ requireResolve = require.resolve.bind(require),
121+} = {}) {
122+let vitestPackageJson;
123+try {
124+vitestPackageJson = requireResolve("vitest/package.json");
125+} catch (error) {
126+if (isMissingVitestResolveError(error)) {
127+const wrappedError = new Error(resolveMissingVitestDependencyMessage(baseDir, fsImpl));
128+wrappedError.code = "OPENCLAW_MISSING_VITEST";
129+throw wrappedError;
130+}
131+throw error;
132+}
96133return path.join(path.dirname(vitestPackageJson), "vitest.mjs");
97134}
98135@@ -529,12 +566,23 @@ function main(argv = process.argv.slice(2), env = process.env) {
529566530567const vitestArgs = resolveImplicitVitestArgs(argv);
531568const spawnEnv = resolveRunVitestSpawnEnv(env, vitestArgs);
569+let vitestCliEntry;
570+try {
571+vitestCliEntry = resolveVitestCliEntry();
572+} catch (error) {
573+if (error instanceof Error && error.code === "OPENCLAW_MISSING_VITEST") {
574+console.error(error.message);
575+process.exit(1);
576+}
577+throw error;
578+}
579+532580const { child, teardown } = spawnWatchedVitestProcess({
533581pnpmArgs: [
534582"exec",
535583"node",
536584 ...resolveVitestNodeArgs(env),
537-resolveVitestCliEntry(),
585+vitestCliEntry,
538586 ...vitestArgs,
539587],
540588spawnParams: resolveVitestSpawnParams(spawnEnv),
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。