PronounsPage/new/setup.mjs
2024-09-11 21:29:22 +02:00

143 lines
4.0 KiB
JavaScript

import fsp from "node:fs/promises";
import fs from "node:fs";
import path from "node:path";
import process from "node:process";
import * as child_process from "node:child_process";
console.log("Setting up project");
const argv = process.argv.slice(2);
const packageManager = argv[0] ?? "pnpm";
let currentlySettingUp = "";
let needsToInstallDependencies = false;
const url = new URL(import.meta.url);
let projectDir = url.pathname
.split("/")
.filter((v) => v && v.length > 0)
.join(path.sep);
// This is a cheap but probably check to see if we're *not* on Windows.
if (path.sep !== "\\") {
// You could inline `path.sep` as "\" but why not go that extra mile
// We're already using it so
projectDir = path.sep + projectDir;
}
projectDir = path.dirname(path.resolve(projectDir));
const legacyDir = path.resolve(projectDir, "..");
function message(str) {
let prefix = "";
if (!!currentlySettingUp && currentlySettingUp.trim().length >= 0) {
prefix = `[${currentlySettingUp}] `;
}
console.log(" " + prefix + str);
}
console.log(`
Project directory: ${projectDir}
Legacy directory: ${legacyDir}
`);
async function symlink(to, from) {
if (!fs.existsSync(from)) {
message(`Creating symlink from ${from} to ${to}`);
await fsp.symlink(to, from, "dir");
} else {
message(`File ${from} already exists - not symlinking to ${to}`);
}
}
// Create temporary symlinks
// This step may very well be removed in the future.
{
currentlySettingUp = "data";
let to, from;
to = path.resolve(legacyDir, "locale");
from = path.resolve(projectDir, "locales");
await symlink(to, from);
to = path.resolve(legacyDir, "public");
from = path.resolve(projectDir, "static");
await symlink(to, from);
}
{
currentlySettingUp = "common";
const commonDir = path.resolve(projectDir, "common");
const commonDistDir = path.resolve(commonDir, "dist");
if (!fs.existsSync(commonDistDir)) {
message("Building common package");
child_process.spawnSync(packageManager, ["run", "build"], {
cwd: commonDir,
stdio: "inherit",
});
}
}
{
currentlySettingUp = "backend";
const backendDir = path.resolve(projectDir, "backend");
const envFile = path.resolve(backendDir, ".env"),
exampleEnvFile = path.resolve(backendDir, "example.env");
if (!fs.existsSync(envFile)) {
message(`Missing .env file for backend, creating from example.env`);
await fsp.cp(exampleEnvFile, envFile);
} else {
message(`Environment file already exists, continuing`);
}
const prismaDistDir = path.resolve(backendDir, "prisma", "dist");
if (!fs.existsSync(prismaDistDir)) {
message("Generating Prisma client");
child_process.spawnSync(packageManager, ["run", "db:generate"], {
cwd: backendDir,
stdio: "inherit",
});
} else {
message("Prisma client has already been generated and is not broken");
}
// This is a cheap fix for a bug that occurs when the .prisma/client
// package has already been linked, but the target (prisma/dist) doesn't exist
const prismaClientFile = path.resolve(
backendDir,
"node_modules",
".prisma",
"client"
);
let shouldFixPrismaClient = true;
if (fs.existsSync(prismaClientFile)) {
shouldFixPrismaClient &&= !(
await fsp.stat(prismaClientFile)
).isDirectory();
}
if (shouldFixPrismaClient) {
message("Fixing .prisma/client package");
if (fs.existsSync(prismaClientFile)) {
await fsp.rm(prismaClientFile);
}
needsToInstallDependencies = true;
}
}
{
currentlySettingUp = "finalise";
if (needsToInstallDependencies) {
message("Installing dependencies");
child_process.spawnSync(packageManager, ["install"], {
cwd: projectDir,
stdio: "inherit",
});
}
}
console.log(`\nDone!`);