mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-10 05:42:49 +00:00
fix: unify connection failure screens and rebuild stale local plugins
This commit is contained in:
1 parent
a72aa5b57b
commit
49fc241e06
9 files changed
+262
-29
No files matched your search
@@ -7,10 +7,12 @@
|
||||
* pinned sha256 and unpacked.
|
||||
*
|
||||
* For development, `--local <dir>` (or TERMIX_LOCAL_PLUGINS) points at a
|
||||
* folder of plugin repos like ../Termix-Plugins. Any plugin built there (has
|
||||
* dist/) is copied in place of its pin, so local plugin changes show up.
|
||||
* folder of plugin repos like ../Termix-Plugins. A bundled plugin there whose
|
||||
* sources changed since its last build is rebuilt first, then any built one
|
||||
* (has dist/) is copied in place of its pin, so local plugin changes show up.
|
||||
*/
|
||||
|
||||
const { execSync } = require("node:child_process");
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const {
|
||||
@@ -18,6 +20,7 @@ const {
|
||||
fetchArtifact,
|
||||
extractArtifact,
|
||||
findLocalPluginBuilds,
|
||||
rebuildLocalPlugins,
|
||||
copyLocalBuild,
|
||||
} = require("./lib/bundled-plugins.cjs");
|
||||
|
||||
@@ -30,6 +33,14 @@ async function main() {
|
||||
const localArg =
|
||||
flag !== -1 ? process.argv[flag + 1] : process.env.TERMIX_LOCAL_PLUGINS;
|
||||
const localDir = localArg ? path.resolve(root, localArg) : null;
|
||||
rebuildLocalPlugins(
|
||||
localDir,
|
||||
new Set(plugins.map((p) => p.id)),
|
||||
(repo, id) => {
|
||||
console.log(`building ${id}`);
|
||||
execSync("npm run build", { cwd: repo, stdio: "inherit" });
|
||||
},
|
||||
);
|
||||
const local = findLocalPluginBuilds(localDir);
|
||||
|
||||
fs.rmSync(destination, { recursive: true, force: true });
|
||||
|
||||
@@ -11,6 +11,8 @@ import {
|
||||
extractArtifact,
|
||||
pinsFromIndex,
|
||||
findLocalPluginBuilds,
|
||||
isLocalBuildStale,
|
||||
rebuildLocalPlugins,
|
||||
copyLocalBuild,
|
||||
} from "./lib/bundled-plugins.cjs";
|
||||
|
||||
@@ -230,3 +232,52 @@ describe("local plugin builds", () => {
|
||||
expect(fs.existsSync(path.join(out, "src"))).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("rebuilding local plugins", () => {
|
||||
function repo(dir: string, name: string, id: string): string {
|
||||
const root = path.join(dir, name);
|
||||
fs.mkdirSync(path.join(root, "src"), { recursive: true });
|
||||
fs.mkdirSync(path.join(root, "node_modules"));
|
||||
fs.writeFileSync(path.join(root, "manifest.json"), JSON.stringify({ id }));
|
||||
fs.writeFileSync(path.join(root, "src", "index.ts"), "x");
|
||||
return root;
|
||||
}
|
||||
|
||||
function touch(file: string, secondsAgo: number) {
|
||||
const time = new Date(Date.now() - secondsAgo * 1000);
|
||||
fs.utimesSync(file, time, time);
|
||||
}
|
||||
|
||||
it("is stale with no dist or with a source newer than the build", () => {
|
||||
const root = repo(tempDir(), "Plugin-A", "a");
|
||||
expect(isLocalBuildStale(root)).toBe(true);
|
||||
|
||||
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);
|
||||
expect(isLocalBuildStale(root)).toBe(false);
|
||||
|
||||
touch(path.join(root, "src", "index.ts"), 0);
|
||||
touch(path.join(root, "dist", "frontend.js"), 30);
|
||||
expect(isLocalBuildStale(root)).toBe(true);
|
||||
});
|
||||
|
||||
it("builds only stale repos for bundled ids that have node_modules", () => {
|
||||
const dir = tempDir();
|
||||
repo(dir, "Plugin-A", "a");
|
||||
repo(dir, "Plugin-B", "b");
|
||||
const noDeps = repo(dir, "Plugin-C", "c");
|
||||
fs.rmSync(path.join(noDeps, "node_modules"), { recursive: true });
|
||||
|
||||
const run: string[] = [];
|
||||
const rebuilt = rebuildLocalPlugins(
|
||||
dir,
|
||||
new Set(["a", "c"]),
|
||||
(_repo: string, id: string) => run.push(id),
|
||||
);
|
||||
expect(rebuilt).toEqual(["a"]);
|
||||
expect(run).toEqual(["a"]);
|
||||
expect(rebuildLocalPlugins(null, new Set(["a"]), () => {})).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -203,6 +203,56 @@ function findLocalPluginBuilds(dir) {
|
||||
return builds;
|
||||
}
|
||||
|
||||
const BUILD_INPUTS = [
|
||||
"src",
|
||||
"locales",
|
||||
"migrations",
|
||||
"manifest.json",
|
||||
"package.json",
|
||||
];
|
||||
|
||||
function newestMtime(target) {
|
||||
if (!fs.existsSync(target)) return 0;
|
||||
const stat = fs.statSync(target);
|
||||
if (!stat.isDirectory()) return stat.mtimeMs;
|
||||
let newest = 0;
|
||||
for (const name of fs.readdirSync(target)) {
|
||||
newest = Math.max(newest, newestMtime(path.join(target, name)));
|
||||
}
|
||||
return newest;
|
||||
}
|
||||
|
||||
/** True when a plugin repo has never been built or its sources changed since. */
|
||||
function isLocalBuildStale(repo) {
|
||||
const built = newestMtime(path.join(repo, "dist"));
|
||||
if (!built) return true;
|
||||
return BUILD_INPUTS.some(
|
||||
(entry) => newestMtime(path.join(repo, entry)) > built,
|
||||
);
|
||||
}
|
||||
|
||||
/** Builds each listed plugin repo whose build is missing or out of date. */
|
||||
function rebuildLocalPlugins(dir, ids, run) {
|
||||
const rebuilt = [];
|
||||
if (!dir || !fs.existsSync(dir)) return rebuilt;
|
||||
for (const name of fs.readdirSync(dir)) {
|
||||
const repo = path.join(dir, name);
|
||||
const manifestPath = path.join(repo, "manifest.json");
|
||||
if (!fs.existsSync(manifestPath)) continue;
|
||||
if (!fs.existsSync(path.join(repo, "node_modules"))) continue;
|
||||
let id;
|
||||
try {
|
||||
({ id } = JSON.parse(fs.readFileSync(manifestPath, "utf8")));
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
if (!ids.has(id) || !isLocalBuildStale(repo)) continue;
|
||||
run(repo, id);
|
||||
rebuilt.push(id);
|
||||
}
|
||||
return rebuilt;
|
||||
}
|
||||
|
||||
/** Copies a local plugin build into the staging folder. */
|
||||
function copyLocalBuild(repo, destination) {
|
||||
fs.mkdirSync(destination, { recursive: true });
|
||||
@@ -216,6 +266,8 @@ function copyLocalBuild(repo, destination) {
|
||||
|
||||
module.exports = {
|
||||
findLocalPluginBuilds,
|
||||
isLocalBuildStale,
|
||||
rebuildLocalPlugins,
|
||||
copyLocalBuild,
|
||||
parseBundledPlugins,
|
||||
pinsFromIndex,
|
||||
|
||||
Reference in new issue
Block a user