branch: main
git.mjs
2991 bytesRaw
import { spawn } from "node:child_process";
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
const fixturesDir = resolve(rootDir, "tests", "fixtures");
export const workersRsBundle = resolve(fixturesDir, "workers-rs-main.bundle");
function run(command, args, options = {}) {
const { cwd, env, input } = options;
return new Promise((resolvePromise, rejectPromise) => {
const child = spawn(command, args, {
cwd,
env: {
...process.env,
GIT_TERMINAL_PROMPT: "0",
...env,
},
stdio: "pipe",
});
let stdout = "";
let stderr = "";
child.stdout.on("data", (chunk) => {
stdout += chunk.toString();
});
child.stderr.on("data", (chunk) => {
stderr += chunk.toString();
});
child.on("error", rejectPromise);
child.on("close", (code) => {
if (code === 0) {
resolvePromise({ stdout, stderr });
return;
}
rejectPromise(
new Error(
`${command} ${args.join(" ")} failed with exit code ${code}\nstdout:\n${stdout}\nstderr:\n${stderr}`,
),
);
});
if (input !== undefined) {
child.stdin.end(input);
}
});
}
export async function makeTempDir(prefix) {
return mkdtemp(join(tmpdir(), `${prefix}-`));
}
export async function cleanupTempDirs(dirs) {
for (const dir of dirs) {
await rm(dir, { recursive: true, force: true });
}
}
export async function git(cwd, args, options = {}) {
return run("git", args, { cwd, ...options });
}
export async function gitStdout(cwd, args, options = {}) {
const { stdout } = await git(cwd, args, options);
return stdout.trim();
}
export async function cloneFixture(bundlePath = workersRsBundle) {
const workDir = await makeTempDir("ripgit-fixture");
const repoDir = join(workDir, "repo");
await run("git", ["clone", bundlePath, repoDir]);
await git(repoDir, ["config", "user.name", "Ripgit E2E"]);
await git(repoDir, ["config", "user.email", "ripgit-e2e@example.com"]);
return { workDir, repoDir };
}
export async function appendLineAndCommit(repoDir, relativePath, line, message) {
const filePath = join(repoDir, relativePath);
const existing = await readFile(filePath, "utf8");
const next = existing.endsWith("\n") ? `${existing}${line}\n` : `${existing}\n${line}\n`;
await writeFile(filePath, next);
await git(repoDir, ["add", relativePath]);
await git(repoDir, ["commit", "-m", message]);
return gitStdout(repoDir, ["rev-parse", "HEAD"]);
}
export async function addRemote(repoDir, name, url) {
await git(repoDir, ["remote", "add", name, url]);
}
export async function pushAsOwner(repoDir, owner, ...args) {
return git(repoDir, ["-c", `http.extraHeader=X-Ripgit-Actor-Name: ${owner}`, ...args]);
}