Files
pom-omp/src/git.ts

44 lines
1.9 KiB
TypeScript

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<string> {
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<void> {
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<string | undefined> {
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<string | undefined> {
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"]);
}