/**
* Shared harness for the merge-fix e2e and eval scripts: builds a repo with a conflicting pull request over
* git as the GITFOR_TOKEN user, and runs a fix. Tokens live in the account's Durable Object, so create one in
* the dev server's settings first. D1_CWD points at the checkout whose dev server is under test (its
* `.wrangler` state holds the D1 directory).
*/
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
export const BASE_URL = (process.env.BASE_URL ?? "http://localhost:3015").replace(/\/$/, "");
const POLL_MS = 3000;
const D1_CWD = process.env.D1_CWD ?? process.cwd();
export const FIX_TIMEOUT_MS = 300_000;
export const CI_TIMEOUT_MS = 60_000;
/** A merge commit lists itself plus two parents in `rev-list --parents`. */
export const MERGE_PARENT_FIELDS = 3;
/** Two generations and one Clef decision for the single hunk. */
export const EXPECTED_MIN_CALLS = 3;
/**
* Git runs with no system or global config, so credential helpers (osxkeychain) never see the token in
* the push URL and never prompt.
*/
const GIT_ENV = { ...process.env, GIT_CONFIG_NOSYSTEM: "1", GIT_CONFIG_GLOBAL: "/dev/null", GIT_TERMINAL_PROMPT: "0" };
export function sh(cmd: string[], cwd?: string): string {
const result = Bun.spawnSync(cmd, { cwd, stdout: "pipe", stderr: "pipe", env: GIT_ENV });
if (result.exitCode !== 0) throw new Error(`${cmd.join(" ")} failed: ${result.stderr.toString()}`);
return result.stdout.toString();
}
export function d1(sql: string): Array<Record<string, unknown>> {
const out = sh(["bunx", "wrangler", "d1", "execute", "gitfor", "--local", "--json", "--command", sql], D1_CWD);
return (JSON.parse(out) as Array<{ results: Array<Record<string, unknown>> }>)[0]?.results ?? [];
}
function requiredToken(): string {
const token = process.env.GITFOR_TOKEN;
if (!token) throw new Error("Set GITFOR_TOKEN to a classic token (repo scope) of a user on the dev server");