mirror of https://github.com/openclaw/openclaw.git
101 lines
3.0 KiB
JavaScript
101 lines
3.0 KiB
JavaScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
import { removePathIfExists } from "./runtime-postbuild-shared.mjs";
|
|
|
|
function linkOrCopyFile(sourcePath, targetPath) {
|
|
try {
|
|
fs.linkSync(sourcePath, targetPath);
|
|
} catch (error) {
|
|
if (error && typeof error === "object" && "code" in error) {
|
|
const code = error.code;
|
|
if (code === "EXDEV" || code === "EPERM" || code === "EMLINK") {
|
|
fs.copyFileSync(sourcePath, targetPath);
|
|
return;
|
|
}
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
function mirrorTreeWithHardlinks(sourceRoot, targetRoot) {
|
|
fs.mkdirSync(targetRoot, { recursive: true });
|
|
const queue = [{ sourceDir: sourceRoot, targetDir: targetRoot }];
|
|
|
|
while (queue.length > 0) {
|
|
const current = queue.pop();
|
|
if (!current) {
|
|
continue;
|
|
}
|
|
|
|
for (const dirent of fs.readdirSync(current.sourceDir, { withFileTypes: true })) {
|
|
const sourcePath = path.join(current.sourceDir, dirent.name);
|
|
const targetPath = path.join(current.targetDir, dirent.name);
|
|
|
|
if (dirent.isDirectory()) {
|
|
fs.mkdirSync(targetPath, { recursive: true });
|
|
queue.push({ sourceDir: sourcePath, targetDir: targetPath });
|
|
continue;
|
|
}
|
|
|
|
if (dirent.isSymbolicLink()) {
|
|
fs.symlinkSync(fs.readlinkSync(sourcePath), targetPath);
|
|
continue;
|
|
}
|
|
|
|
if (!dirent.isFile()) {
|
|
continue;
|
|
}
|
|
|
|
linkOrCopyFile(sourcePath, targetPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
function symlinkType() {
|
|
return process.platform === "win32" ? "junction" : "dir";
|
|
}
|
|
|
|
function linkPluginNodeModules(params) {
|
|
const runtimeNodeModulesDir = path.join(params.runtimePluginDir, "node_modules");
|
|
removePathIfExists(runtimeNodeModulesDir);
|
|
if (!fs.existsSync(params.sourcePluginNodeModulesDir)) {
|
|
return;
|
|
}
|
|
fs.symlinkSync(params.sourcePluginNodeModulesDir, runtimeNodeModulesDir, symlinkType());
|
|
}
|
|
|
|
export function stageBundledPluginRuntime(params = {}) {
|
|
const repoRoot = params.cwd ?? params.repoRoot ?? process.cwd();
|
|
const distRoot = path.join(repoRoot, "dist");
|
|
const runtimeRoot = path.join(repoRoot, "dist-runtime");
|
|
const sourceExtensionsRoot = path.join(repoRoot, "extensions");
|
|
const distExtensionsRoot = path.join(distRoot, "extensions");
|
|
const runtimeExtensionsRoot = path.join(runtimeRoot, "extensions");
|
|
|
|
if (!fs.existsSync(distExtensionsRoot)) {
|
|
removePathIfExists(runtimeRoot);
|
|
return;
|
|
}
|
|
|
|
removePathIfExists(runtimeRoot);
|
|
mirrorTreeWithHardlinks(distRoot, runtimeRoot);
|
|
|
|
for (const dirent of fs.readdirSync(distExtensionsRoot, { withFileTypes: true })) {
|
|
if (!dirent.isDirectory()) {
|
|
continue;
|
|
}
|
|
const runtimePluginDir = path.join(runtimeExtensionsRoot, dirent.name);
|
|
const sourcePluginNodeModulesDir = path.join(sourceExtensionsRoot, dirent.name, "node_modules");
|
|
|
|
linkPluginNodeModules({
|
|
runtimePluginDir,
|
|
sourcePluginNodeModulesDir,
|
|
});
|
|
}
|
|
}
|
|
|
|
if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
|
|
stageBundledPluginRuntime();
|
|
}
|