mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 06:05:24 +00:00
fix: dev stages local plugin builds on paths with spaces and builds them with the local SDK
This commit is contained in:
1 parent
878f1ebaa3
commit
4511cc0a42
4 files changed
+76
-8
No files matched your search
@@ -8,11 +8,12 @@
|
||||
*
|
||||
* For development, `--local <dir>` (or TERMIX_LOCAL_PLUGINS) points at a
|
||||
* folder of plugin repos like ../Termix-Plugins. A plugin there whose sources
|
||||
* changed since its last build is rebuilt first, then any built one (has
|
||||
* changed since its last build is rebuilt first with this checkout's SDK, so
|
||||
* SDK edits apply without publishing, then any built one (has
|
||||
* dist/) is copied in place of its pin, or added when it has no pin.
|
||||
*/
|
||||
|
||||
const { execSync } = require("node:child_process");
|
||||
const { execFileSync } = require("node:child_process");
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const {
|
||||
@@ -21,6 +22,7 @@ const {
|
||||
extractArtifact,
|
||||
findLocalPluginBuilds,
|
||||
rebuildLocalPlugins,
|
||||
localSdkBuildCommand,
|
||||
copyLocalBuild,
|
||||
buildBundledIndex,
|
||||
} = require("./lib/bundled-plugins.cjs");
|
||||
@@ -34,9 +36,10 @@ async function main() {
|
||||
const localArg =
|
||||
flag !== -1 ? process.argv[flag + 1] : process.env.TERMIX_LOCAL_PLUGINS;
|
||||
const localDir = localArg ? path.resolve(root, localArg) : null;
|
||||
const [node, buildArgs] = localSdkBuildCommand();
|
||||
rebuildLocalPlugins(localDir, null, (repo, id) => {
|
||||
console.log(`building ${id}`);
|
||||
execSync("npm run build", { cwd: repo, stdio: "inherit" });
|
||||
execFileSync(node, buildArgs, { cwd: repo, stdio: "inherit" });
|
||||
});
|
||||
const local = findLocalPluginBuilds(localDir);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
buildBundledIndex,
|
||||
findLocalPluginBuilds,
|
||||
isLocalBuildStale,
|
||||
localSdkBuildCommand,
|
||||
rebuildLocalPlugins,
|
||||
copyLocalBuild,
|
||||
} from "./lib/bundled-plugins.cjs";
|
||||
@@ -354,6 +355,40 @@ describe("rebuilding local plugins", () => {
|
||||
expect(isLocalBuildStale(root)).toBe(true);
|
||||
});
|
||||
|
||||
it("is stale when the SDK CLI changed after the build", () => {
|
||||
const root = repo(tempDir(), "Plugin-A", "a");
|
||||
const cli = path.join(tempDir(), "cli");
|
||||
fs.mkdirSync(cli);
|
||||
fs.writeFileSync(path.join(cli, "index.mjs"), "x");
|
||||
fs.mkdirSync(path.join(root, "dist"));
|
||||
fs.writeFileSync(path.join(root, "dist", "frontend.js"), "x");
|
||||
touch(path.join(root, "manifest.json"), 60);
|
||||
touch(path.join(root, "src", "index.ts"), 60);
|
||||
touch(path.join(cli, "index.mjs"), 60);
|
||||
expect(isLocalBuildStale(root, cli)).toBe(false);
|
||||
|
||||
touch(path.join(root, "dist", "frontend.js"), 30);
|
||||
touch(path.join(cli, "index.mjs"), 0);
|
||||
expect(isLocalBuildStale(root, cli)).toBe(true);
|
||||
expect(isLocalBuildStale(root)).toBe(false);
|
||||
});
|
||||
|
||||
it("builds with this checkout's SDK CLI, not the plugin's own", () => {
|
||||
const [command, args] = localSdkBuildCommand();
|
||||
expect(command).toBe(process.execPath);
|
||||
expect(args).toEqual([
|
||||
path.resolve(
|
||||
__dirname,
|
||||
"..",
|
||||
"packages",
|
||||
"plugin-sdk",
|
||||
"cli",
|
||||
"index.mjs",
|
||||
),
|
||||
"build",
|
||||
]);
|
||||
});
|
||||
|
||||
it("builds only stale repos for bundled ids that have node_modules", () => {
|
||||
const dir = tempDir();
|
||||
repo(dir, "Plugin-A", "a");
|
||||
|
||||
+8
-3
@@ -45,7 +45,10 @@ import {
|
||||
} from "./lib/dev-docker.mjs";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const { copyLocalBuild } = require("./lib/bundled-plugins.cjs");
|
||||
const {
|
||||
copyLocalBuild,
|
||||
localSdkBuildCommand,
|
||||
} = require("./lib/bundled-plugins.cjs");
|
||||
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const BACKEND_ENTRY = path.join(
|
||||
@@ -83,7 +86,9 @@ function run(command, args, cwd = root) {
|
||||
const child = spawn(command, args, {
|
||||
cwd,
|
||||
stdio: ["ignore", "inherit", "inherit"],
|
||||
shell: process.platform === "win32",
|
||||
// npm is a .cmd on Windows and needs the shell, but the shell splits
|
||||
// arguments on spaces, so a path like "Personal Projects" gets cut.
|
||||
shell: process.platform === "win32" && !path.isAbsolute(command),
|
||||
});
|
||||
child.on("error", reject);
|
||||
child.on("exit", (code) =>
|
||||
@@ -541,7 +546,7 @@ function watchCoreForDocker() {
|
||||
async function rebuildPlugin({ id, repo }) {
|
||||
log(`building ${id}`);
|
||||
try {
|
||||
await run("npm", ["run", "build"], repo);
|
||||
await run(...localSdkBuildCommand(), repo);
|
||||
} catch (error) {
|
||||
warn(`${id} failed to build: ${error.message}`);
|
||||
return;
|
||||
|
||||
@@ -299,14 +299,37 @@ function newestMtime(target) {
|
||||
}
|
||||
|
||||
/** True when a plugin repo has never been built or its sources changed since. */
|
||||
function isLocalBuildStale(repo) {
|
||||
/** The SDK CLI in this checkout, which dev builds local plugins with. */
|
||||
const LOCAL_SDK_CLI = path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"..",
|
||||
"packages",
|
||||
"plugin-sdk",
|
||||
"cli",
|
||||
);
|
||||
|
||||
/**
|
||||
* True when the build is missing, a source is newer than it, or the SDK CLI
|
||||
* that builds it changed since (sdkCli, when given).
|
||||
*/
|
||||
function isLocalBuildStale(repo, sdkCli) {
|
||||
const built = newestMtime(path.join(repo, "dist"));
|
||||
if (!built) return true;
|
||||
if (sdkCli && newestMtime(sdkCli) > built) return true;
|
||||
return BUILD_INPUTS.some(
|
||||
(entry) => newestMtime(path.join(repo, entry)) > built,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The command that builds a plugin repo with this checkout's SDK instead of
|
||||
* the published one in its node_modules, so SDK edits apply right away.
|
||||
*/
|
||||
function localSdkBuildCommand() {
|
||||
return [process.execPath, [path.join(LOCAL_SDK_CLI, "index.mjs"), "build"]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds each plugin repo whose build is missing or out of date. ids limits
|
||||
* it to those plugins; null builds every one.
|
||||
@@ -325,7 +348,8 @@ function rebuildLocalPlugins(dir, ids, run) {
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
if ((ids && !ids.has(id)) || !isLocalBuildStale(repo)) continue;
|
||||
if ((ids && !ids.has(id)) || !isLocalBuildStale(repo, LOCAL_SDK_CLI))
|
||||
continue;
|
||||
run(repo, id);
|
||||
rebuilt.push(id);
|
||||
}
|
||||
@@ -346,6 +370,7 @@ function copyLocalBuild(repo, destination) {
|
||||
module.exports = {
|
||||
findLocalPluginBuilds,
|
||||
isLocalBuildStale,
|
||||
localSdkBuildCommand,
|
||||
rebuildLocalPlugins,
|
||||
copyLocalBuild,
|
||||
parseBundledPlugins,
|
||||
|
||||
Reference in new issue
Block a user