mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 09:11:26 +00:00
refactor(commands): share daemon runtime warning helper
This commit is contained in:
@@ -3,16 +3,14 @@ import { collectConfigEnvVars } from "../config/env-vars.js";
|
|||||||
import type { OpenClawConfig } from "../config/types.js";
|
import type { OpenClawConfig } from "../config/types.js";
|
||||||
import { resolveGatewayLaunchAgentLabel } from "../daemon/constants.js";
|
import { resolveGatewayLaunchAgentLabel } from "../daemon/constants.js";
|
||||||
import { resolveGatewayProgramArguments } from "../daemon/program-args.js";
|
import { resolveGatewayProgramArguments } from "../daemon/program-args.js";
|
||||||
import {
|
import { resolvePreferredNodePath } from "../daemon/runtime-paths.js";
|
||||||
renderSystemNodeWarning,
|
|
||||||
resolvePreferredNodePath,
|
|
||||||
resolveSystemNodeInfo,
|
|
||||||
} from "../daemon/runtime-paths.js";
|
|
||||||
import { buildServiceEnvironment } from "../daemon/service-env.js";
|
import { buildServiceEnvironment } from "../daemon/service-env.js";
|
||||||
|
import {
|
||||||
|
emitNodeRuntimeWarning,
|
||||||
|
type DaemonInstallWarnFn,
|
||||||
|
} from "./daemon-install-runtime-warning.js";
|
||||||
import type { GatewayDaemonRuntime } from "./daemon-runtime.js";
|
import type { GatewayDaemonRuntime } from "./daemon-runtime.js";
|
||||||
|
|
||||||
type WarnFn = (message: string, title?: string) => void;
|
|
||||||
|
|
||||||
export type GatewayInstallPlan = {
|
export type GatewayInstallPlan = {
|
||||||
programArguments: string[];
|
programArguments: string[];
|
||||||
workingDirectory?: string;
|
workingDirectory?: string;
|
||||||
@@ -32,7 +30,7 @@ export async function buildGatewayInstallPlan(params: {
|
|||||||
token?: string;
|
token?: string;
|
||||||
devMode?: boolean;
|
devMode?: boolean;
|
||||||
nodePath?: string;
|
nodePath?: string;
|
||||||
warn?: WarnFn;
|
warn?: DaemonInstallWarnFn;
|
||||||
/** Full config to extract env vars from (env vars + inline env keys). */
|
/** Full config to extract env vars from (env vars + inline env keys). */
|
||||||
config?: OpenClawConfig;
|
config?: OpenClawConfig;
|
||||||
}): Promise<GatewayInstallPlan> {
|
}): Promise<GatewayInstallPlan> {
|
||||||
@@ -49,13 +47,13 @@ export async function buildGatewayInstallPlan(params: {
|
|||||||
runtime: params.runtime,
|
runtime: params.runtime,
|
||||||
nodePath,
|
nodePath,
|
||||||
});
|
});
|
||||||
if (params.runtime === "node") {
|
await emitNodeRuntimeWarning({
|
||||||
const systemNode = await resolveSystemNodeInfo({ env: params.env });
|
env: params.env,
|
||||||
const warning = renderSystemNodeWarning(systemNode, programArguments[0]);
|
runtime: params.runtime,
|
||||||
if (warning) {
|
nodeProgram: programArguments[0],
|
||||||
params.warn?.(warning, "Gateway runtime");
|
warn: params.warn,
|
||||||
}
|
title: "Gateway runtime",
|
||||||
}
|
});
|
||||||
const serviceEnvironment = buildServiceEnvironment({
|
const serviceEnvironment = buildServiceEnvironment({
|
||||||
env: params.env,
|
env: params.env,
|
||||||
port: params.port,
|
port: params.port,
|
||||||
|
|||||||
71
src/commands/daemon-install-runtime-warning.test.ts
Normal file
71
src/commands/daemon-install-runtime-warning.test.ts
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
const mocks = vi.hoisted(() => ({
|
||||||
|
resolveSystemNodeInfo: vi.fn(),
|
||||||
|
renderSystemNodeWarning: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../daemon/runtime-paths.js", () => ({
|
||||||
|
resolveSystemNodeInfo: mocks.resolveSystemNodeInfo,
|
||||||
|
renderSystemNodeWarning: mocks.renderSystemNodeWarning,
|
||||||
|
}));
|
||||||
|
|
||||||
|
import { emitNodeRuntimeWarning } from "./daemon-install-runtime-warning.js";
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("emitNodeRuntimeWarning", () => {
|
||||||
|
it("skips lookup when runtime is not node", async () => {
|
||||||
|
const warn = vi.fn();
|
||||||
|
await emitNodeRuntimeWarning({
|
||||||
|
env: {},
|
||||||
|
runtime: "bun",
|
||||||
|
warn,
|
||||||
|
title: "Gateway runtime",
|
||||||
|
});
|
||||||
|
expect(mocks.resolveSystemNodeInfo).not.toHaveBeenCalled();
|
||||||
|
expect(mocks.renderSystemNodeWarning).not.toHaveBeenCalled();
|
||||||
|
expect(warn).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("emits warning when system node check returns one", async () => {
|
||||||
|
const warn = vi.fn();
|
||||||
|
mocks.resolveSystemNodeInfo.mockResolvedValue({ path: "/usr/bin/node", version: "18.0.0" });
|
||||||
|
mocks.renderSystemNodeWarning.mockReturnValue("Node too old");
|
||||||
|
|
||||||
|
await emitNodeRuntimeWarning({
|
||||||
|
env: { PATH: "/usr/bin" },
|
||||||
|
runtime: "node",
|
||||||
|
nodeProgram: "/opt/node",
|
||||||
|
warn,
|
||||||
|
title: "Node daemon runtime",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mocks.resolveSystemNodeInfo).toHaveBeenCalledWith({
|
||||||
|
env: { PATH: "/usr/bin" },
|
||||||
|
});
|
||||||
|
expect(mocks.renderSystemNodeWarning).toHaveBeenCalledWith(
|
||||||
|
{ path: "/usr/bin/node", version: "18.0.0" },
|
||||||
|
"/opt/node",
|
||||||
|
);
|
||||||
|
expect(warn).toHaveBeenCalledWith("Node too old", "Node daemon runtime");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not emit when warning helper returns null", async () => {
|
||||||
|
const warn = vi.fn();
|
||||||
|
mocks.resolveSystemNodeInfo.mockResolvedValue(null);
|
||||||
|
mocks.renderSystemNodeWarning.mockReturnValue(null);
|
||||||
|
|
||||||
|
await emitNodeRuntimeWarning({
|
||||||
|
env: {},
|
||||||
|
runtime: "node",
|
||||||
|
nodeProgram: "node",
|
||||||
|
warn,
|
||||||
|
title: "Gateway runtime",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(warn).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
20
src/commands/daemon-install-runtime-warning.ts
Normal file
20
src/commands/daemon-install-runtime-warning.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { renderSystemNodeWarning, resolveSystemNodeInfo } from "../daemon/runtime-paths.js";
|
||||||
|
|
||||||
|
export type DaemonInstallWarnFn = (message: string, title?: string) => void;
|
||||||
|
|
||||||
|
export async function emitNodeRuntimeWarning(params: {
|
||||||
|
env: Record<string, string | undefined>;
|
||||||
|
runtime: string;
|
||||||
|
nodeProgram?: string;
|
||||||
|
warn?: DaemonInstallWarnFn;
|
||||||
|
title: string;
|
||||||
|
}): Promise<void> {
|
||||||
|
if (params.runtime !== "node") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const systemNode = await resolveSystemNodeInfo({ env: params.env });
|
||||||
|
const warning = renderSystemNodeWarning(systemNode, params.nodeProgram);
|
||||||
|
if (warning) {
|
||||||
|
params.warn?.(warning, params.title);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
import { formatNodeServiceDescription } from "../daemon/constants.js";
|
import { formatNodeServiceDescription } from "../daemon/constants.js";
|
||||||
import { resolveNodeProgramArguments } from "../daemon/program-args.js";
|
import { resolveNodeProgramArguments } from "../daemon/program-args.js";
|
||||||
import {
|
import { resolvePreferredNodePath } from "../daemon/runtime-paths.js";
|
||||||
renderSystemNodeWarning,
|
|
||||||
resolvePreferredNodePath,
|
|
||||||
resolveSystemNodeInfo,
|
|
||||||
} from "../daemon/runtime-paths.js";
|
|
||||||
import { buildNodeServiceEnvironment } from "../daemon/service-env.js";
|
import { buildNodeServiceEnvironment } from "../daemon/service-env.js";
|
||||||
import { resolveGatewayDevMode } from "./daemon-install-helpers.js";
|
import { resolveGatewayDevMode } from "./daemon-install-helpers.js";
|
||||||
|
import {
|
||||||
|
emitNodeRuntimeWarning,
|
||||||
|
type DaemonInstallWarnFn,
|
||||||
|
} from "./daemon-install-runtime-warning.js";
|
||||||
import type { NodeDaemonRuntime } from "./node-daemon-runtime.js";
|
import type { NodeDaemonRuntime } from "./node-daemon-runtime.js";
|
||||||
|
|
||||||
type WarnFn = (message: string, title?: string) => void;
|
|
||||||
|
|
||||||
export type NodeInstallPlan = {
|
export type NodeInstallPlan = {
|
||||||
programArguments: string[];
|
programArguments: string[];
|
||||||
workingDirectory?: string;
|
workingDirectory?: string;
|
||||||
@@ -29,7 +27,7 @@ export async function buildNodeInstallPlan(params: {
|
|||||||
runtime: NodeDaemonRuntime;
|
runtime: NodeDaemonRuntime;
|
||||||
devMode?: boolean;
|
devMode?: boolean;
|
||||||
nodePath?: string;
|
nodePath?: string;
|
||||||
warn?: WarnFn;
|
warn?: DaemonInstallWarnFn;
|
||||||
}): Promise<NodeInstallPlan> {
|
}): Promise<NodeInstallPlan> {
|
||||||
const devMode = params.devMode ?? resolveGatewayDevMode();
|
const devMode = params.devMode ?? resolveGatewayDevMode();
|
||||||
const nodePath =
|
const nodePath =
|
||||||
@@ -50,13 +48,13 @@ export async function buildNodeInstallPlan(params: {
|
|||||||
nodePath,
|
nodePath,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (params.runtime === "node") {
|
await emitNodeRuntimeWarning({
|
||||||
const systemNode = await resolveSystemNodeInfo({ env: params.env });
|
env: params.env,
|
||||||
const warning = renderSystemNodeWarning(systemNode, programArguments[0]);
|
runtime: params.runtime,
|
||||||
if (warning) {
|
nodeProgram: programArguments[0],
|
||||||
params.warn?.(warning, "Node daemon runtime");
|
warn: params.warn,
|
||||||
}
|
title: "Node daemon runtime",
|
||||||
}
|
});
|
||||||
|
|
||||||
const environment = buildNodeServiceEnvironment({ env: params.env });
|
const environment = buildNodeServiceEnvironment({ env: params.env });
|
||||||
const description = formatNodeServiceDescription({
|
const description = formatNodeServiceDescription({
|
||||||
|
|||||||
Reference in New Issue
Block a user