import type { CompiledJob, CompiledStep, Segment } from "./compile";
import { runtimeExpansion } from "./segments";
import { RUNTIME_FUNCTIONS } from "./script-runtime";
export const MARKER_PREFIX = "::gitfor::";
const SHELL_COMMANDS: Record<string, string> = {
bash: "bash --noprofile --norc -eo pipefail",
sh: "sh -e",
python: "python3",
python3: "python3",
node: "node",
bun: "bun",
};
const KILL_GRACE_SECONDS = 15;
function doubleQuoted(segments: Segment[]): string {
const body = segments
.map((segment) =>
segment.kind === "text" ? segment.value.replace(/(["\\$`])/g, "\\$1") : runtimeExpansion(segment),
)
.join("");
return `"${body}"`;
}
function singleQuoted(value: string): string {
return `'${value.replace(/'/g, "'\\''")}'`;
}
function exports(env: Array<[string, Segment[]]>): string[] {
return env.map(([name, segments]) => `export ${name}=${doubleQuoted(segments)}`);
}
function heredoc(path: string, content: string): string[] {
let delimiter = `GITFOR_EOF_${crypto.randomUUID().replace(/-/g, "")}`;
while (content.includes(delimiter)) delimiter += "_";
return [`cat > ${path} <<'${delimiter}'`, content, delimiter];
}
function cacheLines(step: CompiledStep): string[] {