#!/usr/bin/env bash # compile-gate.sh — the generator's primary acceptance gate. # # Generates the selected tier's monorepo from regression/tierN/config.toml, then requires the # generated package to `swift build` with ZERO errors. Pass/fail only: error # counts are not a metric. Also diffs each module's skip report against the # committed baseline in regression/tierN/ (JSON files only) so that new # skips in supported categories fail loudly. # # Usage: # scripts/compile-gate.sh [--fresh] # # 1..6 (tier1 = GLib+GObject ... tier6 = full stack), or 'all' # 'all' is the full-stack tier-6 alias and only generates tier 6 # --fresh remove the selected tier's output directory before generating # (use when the generated file set shrinks and stale files would linger) # # Output goes to ${TMPDIR:-/tmp}/gobject-generator-gate/tier-N; a stable path so # incremental swift builds stay fast between runs. set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" GATE_ROOT="${TMPDIR:-/tmp}/gobject-generator-gate" TIER_ARG="${1:-}" FRESH=0 [[ "${2:-}" == "--fresh" ]] && FRESH=1 if [[ -z "$TIER_ARG" ]]; then echo "usage: $0 [--fresh]" >&2 exit 2 fi if [[ "$TIER_ARG" == "all" ]]; then TIERS=(6) else TIERS=("$TIER_ARG") fi echo "==> Building generator" swift build --package-path "$ROOT" BIN="$(swift build --package-path "$ROOT" --show-bin-path)/generator" FAILED=0 run_tier() { local tier="$1" local config="$ROOT/regression/tier${tier}/config.toml" local out="$GATE_ROOT/tier-${tier}" if [[ ! -f "$config" ]]; then echo "!! tier $tier: missing $config" >&2 return 1 fi if [[ "$FRESH" == 1 ]]; then rm -rf "$out" fi mkdir -p "$out" echo "==> Tier $tier: generating into $out" if ! "$BIN" --monorepo-config "$config" --output "$out" --skip-report --format-config "$ROOT/.swift-format" >"$out/generate.log" 2>&1; then echo "!! tier $tier: GENERATION FAILED (see $out/generate.log)" >&2 tail -n 20 "$out/generate.log" >&2 return 1 fi echo "==> Tier $tier: swift build" if ! swift build --package-path "$out" >"$out/build.log" 2>&1; then echo "!! tier $tier: BUILD FAILED (see $out/build.log)" >&2 grep -m 10 'error:' "$out/build.log" >&2 || tail -n 20 "$out/build.log" >&2 return 1 fi echo "==> Tier $tier: swift format lint" if ! swift format lint --strict --configuration "$ROOT/.swift-format" --recursive --parallel "$out/Sources" >"$out/lint.log" 2>&1; then echo "!! tier $tier: LINT FAILED (see $out/lint.log)" >&2 head -n 40 "$out/lint.log" >&2 return 1 fi local baseline="$ROOT/regression/tier${tier}" if [[ -d "$baseline" ]]; then echo "==> Tier $tier: diffing skip reports against $baseline" local tmp_baseline tmp_baseline="$(mktemp -d)" cp "$baseline"/*.json "$tmp_baseline/" 2>/dev/null || true if ! diff -ru "$tmp_baseline" "$out/skip-reports" >"$out/skip-diff.log" 2>&1; then rm -rf "$tmp_baseline" echo "!! tier $tier: SKIP REPORT CHANGED (see $out/skip-diff.log)" >&2 head -n 40 "$out/skip-diff.log" >&2 echo " If the change is intentional (coverage grew), refresh the baseline:" >&2 echo " cp -r $out/skip-reports/*.json $baseline/" >&2 return 1 fi rm -rf "$tmp_baseline" else echo "==> Tier $tier: no skip baseline at $baseline (skipping diff)" fi echo "==> Tier $tier: PASS" } for tier in "${TIERS[@]}"; do if ! run_tier "$tier"; then FAILED=1 fi done exit "$FAILED"