This commit is contained in:
2026-08-10 01:31:55 +02:00
parent 76b586ed85
commit 08e8ffe1e8
+99 -11
View File
@@ -1,14 +1,31 @@
#!/usr/bin/env node
/**
* Cross-platform goose migrate + sqlc generate (Windows / macOS / Linux).
* Cross-platform goose migrate (+ optional sqlc generate).
* Loads monorepo-root `.env` when DATABASE_URL is unset.
*
* Usage: node scripts/migrate.mjs
* Usage:
* node scripts/migrate.mjs # goose only (default)
* node scripts/migrate.mjs --sqlc # also regenerate apps/api/internal/db/sqlc
*
* A 4GiB host is enough for goose + the app. sqlc's go-pgquery/wazero path
* allocates a ~4GiB WASM heap by itself, so it OOMs on 4GiB VPS — skip by
* default; only run --sqlc on a machine with ≥6GiB free (or install a
* prebuilt `sqlc` binary and still prefer ≥6GiB).
*/
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import { loadRootEnv, repoRoot } from "./root-env.mjs";
const args = new Set(process.argv.slice(2));
const wantSqlc =
args.has("--sqlc") ||
process.env.DESCRYBE_SQLC === "1" ||
/^true|yes|on$/i.test(String(process.env.DESCRYBE_SQLC || ""));
/** Prefer this much free/total RAM (MiB) before attempting sqlc go-run/wazero. */
const SQLC_MIN_RAM_MIB = Number(process.env.DESCRYBE_SQLC_MIN_RAM_MIB || 6144);
const env = loadRootEnv(process.env);
if (!env.DATABASE_URL) {
console.error(
@@ -19,8 +36,8 @@ if (!env.DATABASE_URL) {
const apiDir = path.join(repoRoot, "apps", "api");
function run(command, args, opts = {}) {
const r = spawnSync(command, args, {
function run(command, cmdArgs, opts = {}) {
const r = spawnSync(command, cmdArgs, {
cwd: apiDir,
env,
stdio: "inherit",
@@ -36,6 +53,41 @@ function run(command, args, opts = {}) {
}
}
/** Best-effort total RAM in MiB (Linux /proc, Windows wmic, or null). */
function totalRamMiB() {
try {
if (process.platform === "linux") {
const text = fs.readFileSync("/proc/meminfo", "utf8");
const m = text.match(/^MemTotal:\s+(\d+)\s+kB/m);
if (m) return Math.floor(Number(m[1]) / 1024);
}
if (process.platform === "win32") {
const r = spawnSync(
"powershell",
[
"-NoProfile",
"-Command",
"[int]((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory/1MB)",
],
{ encoding: "utf8" },
);
const n = Number(String(r.stdout || "").trim());
if (Number.isFinite(n) && n > 0) return n;
}
} catch {
/* ignore */
}
return null;
}
function hasSqlcBinary() {
const r = spawnSync("sqlc", ["version"], {
encoding: "utf8",
shell: process.platform === "win32",
});
return !(r.error || r.status !== 0);
}
console.log("==> goose up (apps/api/sql/schema)");
run("go", [
"run",
@@ -47,6 +99,29 @@ run("go", [
"up",
]);
if (!wantSqlc) {
console.log(
"==> sqlc skipped (default). 4GiB hosts: goose + app are enough; sqlc needs extra headroom.",
);
console.log(" Regenerate on a larger machine: npm run migrate -- --sqlc");
console.log("==> done");
process.exit(0);
}
const ram = totalRamMiB();
if (ram != null && ram < SQLC_MIN_RAM_MIB && !hasSqlcBinary()) {
console.error(
`[migrate] refusing sqlc: ~${ram}MiB RAM detected (need ≥${SQLC_MIN_RAM_MIB}MiB for wazero go run).`,
);
console.error(
"[migrate] goose already applied. Install a prebuilt sqlc binary, or run --sqlc on a larger host.",
);
console.error(
"[migrate] Or set DESCRYBE_SQLC_MIN_RAM_MIB=0 to force (may OOM).",
);
process.exit(1);
}
console.log("==> sqlc generate");
const sqlc = spawnSync("sqlc", ["generate"], {
cwd: apiDir,
@@ -54,13 +129,26 @@ const sqlc = spawnSync("sqlc", ["generate"], {
stdio: "inherit",
shell: process.platform === "win32",
});
if (sqlc.status !== 0) {
console.log("sqlc not on PATH (or failed); using go run");
run("go", [
"run",
"github.com/sqlc-dev/sqlc/cmd/sqlc@v1.28.0",
"generate",
]);
if (sqlc.status === 0) {
console.log("==> done");
process.exit(0);
}
console.log("sqlc not on PATH (or failed); using go run");
if (ram != null && ram < SQLC_MIN_RAM_MIB) {
console.error(
`[migrate] go run sqlc will likely OOM on ~${ram}MiB (wazero ~4GiB heap).`,
);
console.error(
"[migrate] Install https://docs.sqlc.dev/en/latest/overview/install.html then retry, or use a larger host.",
);
process.exit(1);
}
run("go", [
"run",
"github.com/sqlc-dev/sqlc/cmd/sqlc@v1.28.0",
"generate",
]);
console.log("==> done");