Files
paseo/scripts/postinstall-patches.mjs
T
Mohamed Boudra 63923fdd07 Keep Android timeline still when tapping text (#4090)
* fix(android): keep timeline still when tapping text

Selectable Android text takes touch focus. React Native then scrolls focused children using untransformed coordinates, which moves inverted timelines even though the user did not scroll.\n\nSkip that auto-scroll only for touch-focused, selectable, non-editable text in inverted vertical scroll views, preserving normal focus navigation and editable inputs.

* test(e2e): isolate PR pane fixtures from bots
2026-08-31 12:10:40 +02:00

102 lines
3.1 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+",
},
{
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);