Files
paseo/scripts/postinstall-patches.mjs
Mohamed Boudra 7178583612 Stop Settings navigation from retaining closed views (#4228)
* fix(desktop): stop retaining closed Settings views

Settings rotations left detached detail panes reachable from the web style registry's strong element sets. Backport the upstream weak cleanup design and cover the real Electron bundle with a forced-GC regression.\n\nKeep the established sibling-route topology; compact Back relies on route-name identity.

* test(app): synchronize Mermaid completion layout assertion

The streaming acceptance test can observe the intentional completion remount between visibility and layout sampling. Consult the existing completion promise around that measurement so the transition is not reported as diagram loss.

* test(app): isolate worktree restart from provider startup
2026-09-02 21:27:30 +02:00

108 lines
3.3 KiB
JavaScript

import { copyFileSync, existsSync, mkdirSync, readdirSync, rmSync } from "node:fs";
import { spawnSync } from "node:child_process";
import { join, relative } from "node:path";
// In CI we often install a single workspace (e.g. server/relay/website). Only apply patches
// when the patched dependency is actually present.
// `cwd` is where patch-package must run from. Packages that npm does not hoist to the
// workspace root live in their workspace's own node_modules, and patch-package resolves
// the patch's node_modules/... paths relative to its working directory.
const patchedPackages = [
{
nodeModulesPath: "node_modules/react-native-markdown-display",
patchPrefix: "react-native-markdown-display+",
},
{
nodeModulesPath: "node_modules/react-native",
patchPrefix: "react-native+",
},
// Remove after react-native-unistyles ships
// https://github.com/jpudysz/react-native-unistyles/pull/1203.
{
nodeModulesPath: "node_modules/react-native-unistyles",
patchPrefix: "react-native-unistyles+",
},
{
nodeModulesPath: "node_modules/react-native-draggable-flatlist",
patchPrefix: "react-native-draggable-flatlist+",
},
{
nodeModulesPath: "node_modules/react-native-gesture-handler",
patchPrefix: "react-native-gesture-handler+",
},
{
nodeModulesPath: "node_modules/react-native-svg",
patchPrefix: "react-native-svg+",
},
{
nodeModulesPath: "node_modules/@mattermost/react-native-paste-input",
patchPrefix: "@mattermost+react-native-paste-input+",
},
{
nodeModulesPath: "packages/server/node_modules/@opencode-ai/sdk",
patchPrefix: "@opencode-ai+sdk+",
cwd: "packages/server",
},
];
const installedPackages = patchedPackages.filter(({ nodeModulesPath }) =>
existsSync(nodeModulesPath),
);
if (!existsSync("patches") || installedPackages.length === 0) {
process.exit(0);
}
const patchFiles = readdirSync("patches").filter((file) => file.endsWith(".patch"));
// Group patch files by the directory patch-package must run from.
const patchFilesByCwd = new Map();
for (const { patchPrefix, cwd = "." } of installedPackages) {
const files = patchFiles.filter((file) => file.startsWith(patchPrefix));
if (files.length === 0) {
continue;
}
const group = patchFilesByCwd.get(cwd) ?? [];
group.push(...files);
patchFilesByCwd.set(cwd, group);
}
if (patchFilesByCwd.size === 0) {
process.exit(0);
}
const isWindows = process.platform === "win32";
const cmd = isWindows ? "patch-package.cmd" : "patch-package";
let groupIndex = 0;
for (const [cwd, files] of patchFilesByCwd) {
groupIndex += 1;
const tempPatchDir = join(".tmp", `postinstall-patches-${process.pid}-${groupIndex}`);
mkdirSync(tempPatchDir, { recursive: true });
for (const patchFile of files) {
copyFileSync(join("patches", patchFile), join(tempPatchDir, patchFile));
}
let result;
try {
result = spawnSync(cmd, ["--patch-dir", relative(cwd, tempPatchDir)], {
cwd,
shell: isWindows,
stdio: "inherit",
windowsHide: true,
});
} finally {
rmSync(tempPatchDir, { recursive: true, force: true });
}
if (result.error) {
console.error("postinstall-patches: patch-package failed to spawn:", result.error.message);
}
if (result.status !== 0) {
process.exit(result.status ?? 1);
}
}
process.exit(0);