





















@@ -1,5 +1,7 @@
11import { spawnSync } from "node:child_process";
2-import { readFileSync } from "node:fs";
2+import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3+import { tmpdir } from "node:os";
4+import { join } from "node:path";
35import { describe, expect, it } from "vitest";
4657const SCRIPT_PATH = "scripts/install.sh";
@@ -123,4 +125,52 @@ describe("install.sh macOS Homebrew Node behavior", () => {
123125expect(result.stdout).not.toContain("Node.js v24 was installed");
124126expect(result.stdout).not.toContain("Add this to your shell profile");
125127});
128+129+it("falls back when gum reports raw-mode ioctl failures", () => {
130+expect(script).toContain("setrawmode|inappropriate ioctl");
131+expect(script).toContain(
132+'if "$GUM" spin --spinner dot --title "$title" -- "$@" >"$gum_out" 2>"$gum_err"; then',
133+);
134+expect(script).toContain(
135+'if is_gum_raw_mode_failure "$gum_out" || is_gum_raw_mode_failure "$gum_err"; then',
136+);
137+expect(script).toContain(
138+'ui_warn "Spinner unavailable in this terminal; continuing without spinner"',
139+);
140+expect(script).toContain('"$@"\n return $?');
141+});
142+143+it("reruns spinner-wrapped commands when gum reports ioctl failure", () => {
144+const dir = mkdtempSync(join(tmpdir(), "openclaw-install-sh-gum-"));
145+try {
146+const gumPath = join(dir, "gum");
147+const commandPath = join(dir, "command");
148+const markerPath = join(dir, "marker");
149+writeFileSync(
150+gumPath,
151+"#!/usr/bin/env bash\nprintf 'inappropriate ioctl for device\\n'\nexit 0\n",
152+{ mode: 0o755 },
153+);
154+writeFileSync(commandPath, `#!/usr/bin/env bash\nprintf 'ran' >"${markerPath}"\n`, {
155+mode: 0o755,
156+});
157+158+const result = runInstallShell(`
159+ set -euo pipefail
160+ source "${SCRIPT_PATH}"
161+ gum_is_tty() { return 0; }
162+ GUM="${gumPath}"
163+ run_with_spinner "Installing node" "${commandPath}"
164+ cat "${markerPath}"
165+ `);
166+167+expect(result.status).toBe(0);
168+expect(result.stdout).toContain(
169+"Spinner unavailable in this terminal; continuing without spinner",
170+);
171+expect(result.stdout).toContain("ran");
172+} finally {
173+rmSync(dir, { recursive: true, force: true });
174+}
175+});
126176});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。