#!/usr/bin/env bash # scripts/quality/run-all.sh # # Run every local quality gate in sequence. Each gate is independent; # a failure does not stop the rest (we collect failures and report at # the end). Use this before tagging a release or before showing the # repo to an external reviewer. # # Wall-time budget on a typical dev laptop (M-series Mac): # license-headers.sh ~1 s # check-markdown-links.py ~2 s # sanitizers.sh ~3 min # coverage.sh ~2 min # clang-tidy.sh ~2 min (depends on header count) # multi-compiler.sh ~5 min (per compiler) # reproducible-build.sh ~6 min # cgal-version-matrix.sh ~5 min per CGAL version # ───────────────────────────── # TOTAL ~25–40 min # # Usage: # bash scripts/quality/run-all.sh # everything # bash scripts/quality/run-all.sh --fast # skip the slow gates # (cgal-matrix, multi-compiler, # coverage, reproducible) # # Exit code: number of failed gates (so 0 = green). set -uo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" cd "$ROOT" FAST=0 [ "${1:-}" = "--fast" ] && FAST=1 GATES_FAST=( "License headers | bash scripts/quality/license-headers.sh" "Markdown links | python3 scripts/check-markdown-links.py" "Sanitizers | bash scripts/quality/sanitizers.sh" "clang-tidy | bash scripts/quality/clang-tidy.sh" ) GATES_SLOW=( "Coverage | bash scripts/quality/coverage.sh" "Multi-compiler | bash scripts/quality/multi-compiler.sh" "Reproducible build | bash scripts/quality/reproducible-build.sh" "CGAL version matrix | bash scripts/quality/cgal-version-matrix.sh" ) if [ "$FAST" -eq 1 ]; then GATES=("${GATES_FAST[@]}") else GATES=("${GATES_FAST[@]}" "${GATES_SLOW[@]}") fi LOG_DIR="build-quality-logs" mkdir -p "$LOG_DIR" echo "============================================================" echo " conformallab++ local quality gates" echo " mode: $([ $FAST -eq 1 ] && echo 'FAST (4 gates)' || echo "FULL (${#GATES[@]} gates)")" echo " logs: $LOG_DIR/" echo "============================================================" results="" failed=0 i=0 for entry in "${GATES[@]}"; do i=$((i + 1)) name="${entry%%|*}" name="${name%%[[:space:]]*([[:space:]])}" # trim trailing space cmd="${entry##*|}" cmd="${cmd##[[:space:]]}" # Slug-safe filename slug=$(echo "$name" | tr ' /[:upper:]' '_-[:lower:]' | tr -cd 'a-z0-9_-') log="$LOG_DIR/$slug.log" echo echo "──── [$i/${#GATES[@]}] $name ────" if eval "$cmd" >"$log" 2>&1; then echo " OK ($log)" results="${results} PASS $name " else rc=$? echo " FAIL (rc=$rc) — see $log" echo " last 20 lines:" tail -20 "$log" | sed 's/^/ /' results="${results} FAIL $name ($log) " failed=$((failed + 1)) fi done echo echo "============================================================" echo " Summary" echo "============================================================" printf "%s" "$results" echo echo " failed: $failed / ${#GATES[@]}" exit $failed