





















@@ -0,0 +1,93 @@
1+import { spawnSync } from "node:child_process";
2+import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3+import { tmpdir } from "node:os";
4+import path from "node:path";
5+import { afterEach, describe, expect, it } from "vitest";
6+7+const tempDirs: string[] = [];
8+const scriptPath = "scripts/package-mac-app.sh";
9+10+function makePlist(): string {
11+const dir = mkdtempSync(path.join(tmpdir(), "openclaw-plistbuddy-"));
12+tempDirs.push(dir);
13+const plist = path.join(dir, "Info.plist");
14+writeFileSync(
15+plist,
16+[
17+'<?xml version="1.0" encoding="UTF-8"?>',
18+'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
19+'<plist version="1.0">',
20+"<dict>",
21+"<key>CFBundleIdentifier</key>",
22+"<string>old.bundle</string>",
23+"</dict>",
24+"</plist>",
25+"",
26+].join("\n"),
27+"utf8",
28+);
29+return plist;
30+}
31+32+function runHelper(script: string) {
33+return spawnSync("bash", ["-lc", script], {
34+cwd: process.cwd(),
35+encoding: "utf8",
36+});
37+}
38+39+afterEach(() => {
40+for (const dir of tempDirs.splice(0)) {
41+rmSync(dir, { recursive: true, force: true });
42+}
43+});
44+45+describe("package-mac-app plist stamping", () => {
46+it("does not mask required Info.plist stamp failures", () => {
47+const script = readFileSync(scriptPath, "utf8");
48+const stampBlock = script.slice(
49+script.indexOf("plist_set_string_required"),
50+script.indexOf('echo "🚚 Copying binary"'),
51+);
52+53+expect(stampBlock).toContain("plist_set_string_required");
54+expect(stampBlock).not.toContain("|| true");
55+});
56+57+it.runIf(process.platform === "darwin")(
58+"sets required strings and fails when the plist cannot be stamped",
59+() => {
60+const plist = makePlist();
61+const result = runHelper(`
62+ set -euo pipefail
63+ source scripts/lib/plistbuddy.sh
64+ plist_set_string_required ${JSON.stringify(plist)} CFBundleIdentifier 'ai.openclaw.test'
65+ /usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' ${JSON.stringify(plist)}
66+ broken="$(mktemp -d)"
67+ plist_set_string_required "$broken" CFBundleIdentifier broken
68+ `);
69+70+expect(result.status).toBe(1);
71+expect(result.stdout).toContain("ai.openclaw.test");
72+expect(result.stderr).toContain("Error Reading File");
73+},
74+);
75+76+it.runIf(process.platform === "darwin")("adds optional strings and booleans", () => {
77+const plist = makePlist();
78+const result = runHelper(`
79+ set -euo pipefail
80+ source scripts/lib/plistbuddy.sh
81+ plist_set_or_add_string ${JSON.stringify(plist)} SUFeedURL ''
82+ plist_set_or_add_string ${JSON.stringify(plist)} SUPublicEDKey 'key"with\\\\slashes'
83+ plist_set_or_add_bool ${JSON.stringify(plist)} SUEnableAutomaticChecks false
84+ /usr/libexec/PlistBuddy -c 'Print :SUFeedURL' ${JSON.stringify(plist)}
85+ /usr/libexec/PlistBuddy -c 'Print :SUPublicEDKey' ${JSON.stringify(plist)}
86+ /usr/libexec/PlistBuddy -c 'Print :SUEnableAutomaticChecks' ${JSON.stringify(plist)}
87+ `);
88+89+expect(result.status).toBe(0);
90+expect(result.stdout).toContain('key"with\\\\slashes');
91+expect(result.stdout).toContain("false");
92+});
93+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。