mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-23 01:32:40 +00:00
138 lines
4.9 KiB
JavaScript
138 lines
4.9 KiB
JavaScript
import { execFile } from "node:child_process";
|
|
import {
|
|
access,
|
|
cp,
|
|
mkdir,
|
|
mkdtemp,
|
|
readFile,
|
|
rm,
|
|
stat,
|
|
symlink,
|
|
utimes,
|
|
writeFile,
|
|
} from "node:fs/promises";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { promisify } from "node:util";
|
|
import { describe, expect, test } from "vitest";
|
|
|
|
const desktopDir = path.resolve(import.meta.dirname, "..");
|
|
const repoRoot = path.resolve(desktopDir, "../..");
|
|
const execFileAsync = promisify(execFile);
|
|
const npmCommand = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
const prerequisite = "npm run dev:prerequisites";
|
|
|
|
describe("desktop dev build contract", () => {
|
|
test("runs one prerequisite before either platform dev entry point", async () => {
|
|
const packageJson = JSON.parse(await readFile(path.join(desktopDir, "package.json"), "utf8"));
|
|
const devScript = await readFile(path.join(import.meta.dirname, "dev.sh"), "utf8");
|
|
|
|
expect(packageJson.scripts.predev).toBe(prerequisite);
|
|
expect(packageJson.scripts["predev:win"]).toBe(prerequisite);
|
|
expect(packageJson.scripts["dev:prerequisites"]).toBe(
|
|
"npm --prefix ../.. run build:server-deps && npm --prefix ../.. run build --workspace=@getpaseo/server",
|
|
);
|
|
expect(packageJson.scripts.dev).toBe("./scripts/dev.sh");
|
|
expect(packageJson.scripts["dev:win"]).toBe("powershell ./scripts/dev.ps1");
|
|
expect(devScript.indexOf("npm run build:main")).toBeLessThan(
|
|
devScript.indexOf('exec node "$SCRIPT_DIR/dev-runner.mjs"'),
|
|
);
|
|
});
|
|
|
|
test("builds the private runtime fixture before renderer acceptance", async () => {
|
|
const packageJson = JSON.parse(await readFile(path.join(desktopDir, "package.json"), "utf8"));
|
|
|
|
expect(packageJson.scripts["pretest:e2e:renderer"]).toBe(
|
|
"npm --prefix ../.. run build:workspace-runtime-fixture",
|
|
);
|
|
});
|
|
|
|
test.each(["missing", "stale"])(
|
|
"the public prerequisite repairs %s server artifacts in an isolated checkout",
|
|
async (initialState) => {
|
|
const isolatedRoot = await createIsolatedBuildCheckout();
|
|
const serverExport = path.join(isolatedRoot, "packages/server/dist/server/server/exports.js");
|
|
const sourceExport = path.join(isolatedRoot, "packages/server/src/server/exports.ts");
|
|
|
|
if (initialState === "stale") {
|
|
await mkdir(path.dirname(serverExport), { recursive: true });
|
|
await writeFile(serverExport, "// stale isolated artifact\n");
|
|
const staleTime = new Date(0);
|
|
await utimes(serverExport, staleTime, staleTime);
|
|
}
|
|
|
|
try {
|
|
await runPrerequisite(isolatedRoot);
|
|
await expect(access(serverExport)).resolves.toBeUndefined();
|
|
expect(await readFile(serverExport, "utf8")).not.toContain("stale isolated artifact");
|
|
expect((await stat(serverExport)).mtimeMs).toBeGreaterThanOrEqual(
|
|
(await stat(sourceExport)).mtimeMs,
|
|
);
|
|
} finally {
|
|
await rm(isolatedRoot, { recursive: true, force: true });
|
|
}
|
|
},
|
|
70_000,
|
|
);
|
|
});
|
|
|
|
async function createIsolatedBuildCheckout() {
|
|
const isolatedRoot = await mkdtemp(path.join(os.tmpdir(), "paseo-desktop-build-contract-"));
|
|
const packageDirectories = [
|
|
"packages/client",
|
|
"packages/desktop",
|
|
"packages/highlight",
|
|
"packages/protocol",
|
|
"packages/relay",
|
|
"packages/server",
|
|
"packages/workspace-runtime-contract",
|
|
"packages/workspace-helper",
|
|
];
|
|
|
|
try {
|
|
await Promise.all([
|
|
...["package.json", "package-lock.json", "tsconfig.base.json", "tsconfig.json"].map((file) =>
|
|
cp(path.join(repoRoot, file), path.join(isolatedRoot, file)),
|
|
),
|
|
cp(path.join(repoRoot, "scripts"), path.join(isolatedRoot, "scripts"), {
|
|
recursive: true,
|
|
}),
|
|
...packageDirectories.map(async (relativeDirectory) => {
|
|
const target = path.join(isolatedRoot, relativeDirectory);
|
|
await mkdir(path.dirname(target), { recursive: true });
|
|
await cp(path.join(repoRoot, relativeDirectory), target, {
|
|
recursive: true,
|
|
filter: (source) =>
|
|
!source.endsWith(`${path.sep}dist`) &&
|
|
!source.endsWith(`${path.sep}node_modules`) &&
|
|
!source.endsWith(`${path.sep}test-results`),
|
|
});
|
|
}),
|
|
]);
|
|
await symlink(path.join(repoRoot, "node_modules"), path.join(isolatedRoot, "node_modules"));
|
|
await Promise.all(
|
|
packageDirectories.map((relativeDirectory) =>
|
|
symlink(
|
|
path.join(repoRoot, relativeDirectory, "node_modules"),
|
|
path.join(isolatedRoot, relativeDirectory, "node_modules"),
|
|
),
|
|
),
|
|
);
|
|
return isolatedRoot;
|
|
} catch (error) {
|
|
await rm(isolatedRoot, { recursive: true, force: true });
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async function runPrerequisite(isolatedRoot) {
|
|
try {
|
|
await execFileAsync(npmCommand, ["run", "dev:prerequisites", "--workspace=@getpaseo/desktop"], {
|
|
cwd: isolatedRoot,
|
|
timeout: 60_000,
|
|
});
|
|
} catch (error) {
|
|
throw new Error(`${error.stdout ?? ""}\n${error.stderr ?? ""}`, { cause: error });
|
|
}
|
|
}
|