mirror of
https://github.com/penpot/penpot.git
synced 2026-08-01 10:56:20 +00:00
🐛 Relocate MCP run directory out of the npm-managed install directory
For the npm MCP package, adjust the launcher to specifically prepare the runtime directory: The package contents are copied once per version to a runtime directory owned by the launcher. The npm-owned package directory cannot be used. While installing there worked for older npm/npx version, we have to assume it is read-only. Fixes #9947
This commit is contained in:
parent
aee555ff6e
commit
93b5baa9fc
@ -1,21 +1,61 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// Entry point (bin) of the published @penpot/mcp package.
|
||||||
|
// This script is not intended to be run from a source checkout; there, use
|
||||||
|
// `pnpm run bootstrap` directly, as described in the README.
|
||||||
|
|
||||||
const { execSync } = require("child_process");
|
const { execSync } = require("child_process");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
const os = require("os");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
const root = path.resolve(__dirname, "..");
|
const packageRoot = path.resolve(__dirname, "..");
|
||||||
const pkg = require(path.join(root, "package.json"));
|
const pkg = require(path.join(packageRoot, "package.json"));
|
||||||
|
|
||||||
function pnpmVersion() {
|
function pnpmVersion() {
|
||||||
const match = (pkg.packageManager || "").match(/^pnpm@([^+]+)/);
|
const match = (pkg.packageManager || "").match(/^pnpm@([^+]+)/);
|
||||||
return match ? match[1] : "latest";
|
return match ? match[1] : "latest";
|
||||||
}
|
}
|
||||||
|
|
||||||
function run(command) {
|
/**
|
||||||
execSync(command, { cwd: root, stdio: "inherit" });
|
* Prepares the directory in which to bootstrap and run.
|
||||||
|
*
|
||||||
|
* The package contents are copied once per version to a runtime directory
|
||||||
|
* owned by this launcher. The npm-owned package directory cannot be used;
|
||||||
|
* we have to assume it is read-only (#9947).
|
||||||
|
*
|
||||||
|
* @returns {string} the directory to run the bootstrap in
|
||||||
|
*/
|
||||||
|
function prepareRuntimeRoot() {
|
||||||
|
const cacheBase = process.env.XDG_CACHE_HOME || path.join(os.homedir(), ".cache");
|
||||||
|
const runtimeRoot = path.join(cacheBase, "penpot-mcp", pkg.version);
|
||||||
|
if (fs.existsSync(runtimeRoot)) {
|
||||||
|
return runtimeRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy to a temporary sibling first and rename, so an interrupted copy
|
||||||
|
// cannot leave a partial runtime directory behind
|
||||||
|
console.log(`Preparing runtime directory ${runtimeRoot} ...`);
|
||||||
|
const tempRoot = `${runtimeRoot}.tmp-${process.pid}`;
|
||||||
|
fs.rmSync(tempRoot, { recursive: true, force: true });
|
||||||
|
fs.cpSync(packageRoot, tempRoot, {
|
||||||
|
recursive: true,
|
||||||
|
filter: (src) => path.basename(src) !== "node_modules",
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
fs.renameSync(tempRoot, runtimeRoot);
|
||||||
|
} catch (error) {
|
||||||
|
fs.rmSync(tempRoot, { recursive: true, force: true });
|
||||||
|
if (!fs.existsSync(runtimeRoot)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
// a concurrent launch created the runtime directory in the meantime; use it
|
||||||
|
}
|
||||||
|
return runtimeRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const root = prepareRuntimeRoot();
|
||||||
|
|
||||||
// pnpm-lock.yaml is hard-excluded by npm pack; it is shipped as pnpm-lock.dist.yaml
|
// pnpm-lock.yaml is hard-excluded by npm pack; it is shipped as pnpm-lock.dist.yaml
|
||||||
// and restored here before bootstrap runs.
|
// and restored here before bootstrap runs.
|
||||||
const distLock = path.join(root, "pnpm-lock.dist.yaml");
|
const distLock = path.join(root, "pnpm-lock.dist.yaml");
|
||||||
@ -25,7 +65,7 @@ if (fs.existsSync(distLock)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
run(`npx -y pnpm@${pnpmVersion()} run bootstrap`);
|
execSync(`npx -y pnpm@${pnpmVersion()} run bootstrap`, { cwd: root, stdio: "inherit" });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
process.exit(error.status ?? 1);
|
process.exit(error.status ?? 1);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user