321 lines · 14.8 KB
import type { CompiledJob, CompiledStep, Segment } from "./compile";
import type { CompiledAction, CompiledDocker } from "./actions/compile-action";
import { inputVariable } from "./actions/manifest";
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 artifactPath(path: string): string {
  if (path === "~") return '"$HOME"';
  if (path.startsWith("~/")) return `"$HOME"/${singleQuoted(path.slice(2))}`;
  return singleQuoted(path);
}

function exports(env: Array<[string, Segment[]]>): string[] {
  return env.map(([name, segments]) => `export ${name}=${doubleQuoted(segments)}`);
}