import { execFile } from "node:child_process"; import { promisify } from "node:util"; import { join } from "node:path"; import type { PomConfig, PomState } from "./domain"; import { stage } from "./domain"; import { pathExists } from "./persistence"; const execFileAsync = promisify(execFile); async function git(root: string, args: string[]): Promise { const result = await execFileAsync("git", ["-C", root, ...args], { maxBuffer: 4 * 1024 * 1024 }); return result.stdout.trim(); } export async function ensureGit(state: PomState, config: PomConfig): Promise { if (config.gitMode === "off") return; if (!(await pathExists(join(state.projectRoot, ".git")))) { await git(state.projectRoot, ["init"]); await git(state.projectRoot, ["config", "user.name", "POM Production Kernel"]); await git(state.projectRoot, ["config", "user.email", "pom@local.invalid"]); } } export async function enterStageBranch(state: PomState, config: PomConfig): Promise { if (config.gitMode !== "branch-per-stage") return undefined; await ensureGit(state, config); const spec = stage(state.currentStage); const branch = `pom/stage-${spec.id}-${spec.slug}`; const branches = await git(state.projectRoot, ["branch", "--format=%(refname:short)"]); if (branches.split("\n").includes(branch)) await git(state.projectRoot, ["switch", branch]); else await git(state.projectRoot, ["switch", "-c", branch]); return branch; } export async function checkpointStage(state: PomState, config: PomConfig, label: string): Promise { if (config.gitMode === "off") return undefined; await ensureGit(state, config); await git(state.projectRoot, ["add", "-A"]); const status = await git(state.projectRoot, ["status", "--porcelain"]); if (!status) return undefined; await git(state.projectRoot, ["commit", "-m", label]); return git(state.projectRoot, ["rev-parse", "--short", "HEAD"]); }