docs: add bun install support
This commit is contained in:
106
scripts/postinstall.js
Normal file
106
scripts/postinstall.js
Normal file
@@ -0,0 +1,106 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
function isBunInstall() {
|
||||
const ua = process.env.npm_config_user_agent ?? "";
|
||||
return ua.includes("bun/");
|
||||
}
|
||||
|
||||
function getRepoRoot() {
|
||||
const here = path.dirname(fileURLToPath(import.meta.url));
|
||||
return path.resolve(here, "..");
|
||||
}
|
||||
|
||||
function run(cmd, args, opts = {}) {
|
||||
const res = spawnSync(cmd, args, { stdio: "inherit", ...opts });
|
||||
if (typeof res.status === "number") return res.status;
|
||||
return 1;
|
||||
}
|
||||
|
||||
function applyPatchIfNeeded(opts) {
|
||||
const patchPath = path.resolve(opts.patchPath);
|
||||
if (!fs.existsSync(patchPath)) {
|
||||
throw new Error(`missing patch: ${patchPath}`);
|
||||
}
|
||||
|
||||
const targetDir = path.resolve(opts.targetDir);
|
||||
if (!fs.existsSync(targetDir) || !fs.statSync(targetDir).isDirectory()) {
|
||||
console.warn(`[postinstall] skip missing target: ${targetDir}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const gitArgsBase = ["apply", "--unsafe-paths", "--whitespace=nowarn"];
|
||||
const reverseCheck = [
|
||||
...gitArgsBase,
|
||||
"--reverse",
|
||||
"--check",
|
||||
"--directory",
|
||||
targetDir,
|
||||
patchPath,
|
||||
];
|
||||
const forwardCheck = [
|
||||
...gitArgsBase,
|
||||
"--check",
|
||||
"--directory",
|
||||
targetDir,
|
||||
patchPath,
|
||||
];
|
||||
const apply = [...gitArgsBase, "--directory", targetDir, patchPath];
|
||||
|
||||
// Already applied?
|
||||
if (run("git", reverseCheck, { stdio: "ignore" }) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (run("git", forwardCheck, { stdio: "ignore" }) !== 0) {
|
||||
throw new Error(`patch does not apply cleanly: ${path.basename(patchPath)}`);
|
||||
}
|
||||
|
||||
const status = run("git", apply);
|
||||
if (status !== 0) {
|
||||
throw new Error(`failed applying patch: ${path.basename(patchPath)}`);
|
||||
}
|
||||
}
|
||||
|
||||
function extractPackageName(key) {
|
||||
if (key.startsWith("@")) {
|
||||
const idx = key.indexOf("@", 1);
|
||||
if (idx === -1) return key;
|
||||
return key.slice(0, idx);
|
||||
}
|
||||
const idx = key.lastIndexOf("@");
|
||||
if (idx <= 0) return key;
|
||||
return key.slice(0, idx);
|
||||
}
|
||||
|
||||
function main() {
|
||||
if (!isBunInstall()) return;
|
||||
|
||||
const repoRoot = getRepoRoot();
|
||||
process.chdir(repoRoot);
|
||||
|
||||
const pkgPath = path.join(repoRoot, "package.json");
|
||||
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
||||
const patched = pkg?.pnpm?.patchedDependencies ?? {};
|
||||
|
||||
// Bun does not support pnpm.patchedDependencies. Apply these patch files to
|
||||
// node_modules packages as a best-effort compatibility layer.
|
||||
for (const [key, relPatchPath] of Object.entries(patched)) {
|
||||
if (typeof relPatchPath !== "string" || !relPatchPath.trim()) continue;
|
||||
const pkgName = extractPackageName(String(key));
|
||||
if (!pkgName) continue;
|
||||
applyPatchIfNeeded({
|
||||
targetDir: path.join("node_modules", ...pkgName.split("/")),
|
||||
patchPath: relPatchPath,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
main();
|
||||
} catch (err) {
|
||||
console.error(String(err));
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user