44 lines
1.9 KiB
TypeScript
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"]);
|
|
}
|