170 lines
5.4 KiB
Bash
170 lines
5.4 KiB
Bash
#!/usr/bin/env bash
|
|
# Phase 0 aggregator — runs every check in .github/workflows/ci.yml locally and
|
|
# reports a single pass/fail summary. Use this as the "did I set everything up
|
|
# right?" one-liner for new teammates.
|
|
#
|
|
# Pieces run, in order:
|
|
# 1. Rule R2 boundary (scripts/check_pdfium_boundary.sh)
|
|
# 2. Engine (cmake configure + build + ctest)
|
|
# 3. Gateway (pip install -e [dev] + ruff + pytest, in gateway/)
|
|
# 4. WASM hello-world (cmake configure + build + node hello.test.mjs)
|
|
#
|
|
# Skips (not failures) are reported when a toolchain isn't present — e.g. no
|
|
# Emscripten on PATH skips WASM. Each piece runs independently; a failure in
|
|
# one does not abort later pieces.
|
|
#
|
|
# Usage:
|
|
# ./scripts/test_phase0.sh # auto-pick preset by OS
|
|
# ./scripts/test_phase0.sh linux-asan # override preset
|
|
# PHASE0_BINARY_DIR=/tmp/build ./scripts/test_phase0.sh
|
|
# SKIP_WASM=1 ./scripts/test_phase0.sh
|
|
#
|
|
# Compatible with bash 3.2 (macOS default) — uses parallel indexed arrays
|
|
# instead of associative arrays.
|
|
set -uo pipefail # NOT -e: we want to collect failures, not abort on first
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "${REPO_ROOT}"
|
|
|
|
PRESET="${1:-}"
|
|
if [[ -z "${PRESET}" ]]; then
|
|
case "$(uname -s)" in
|
|
Darwin*) PRESET=macos-debug ;;
|
|
*) PRESET=linux-debug ;;
|
|
esac
|
|
fi
|
|
BINARY_DIR="${PHASE0_BINARY_DIR:-}"
|
|
|
|
STEPS=()
|
|
STATUSES=()
|
|
LAST_STATUS=PASS
|
|
|
|
record() {
|
|
STEPS+=("$1")
|
|
STATUSES+=("$2")
|
|
LAST_STATUS="$2"
|
|
}
|
|
|
|
run_step() {
|
|
local name="$1"; shift
|
|
echo
|
|
echo ">> [${name}]"
|
|
if "$@"; then
|
|
record "${name}" PASS
|
|
echo " [${name}] OK"
|
|
else
|
|
local rc=$?
|
|
record "${name}" FAIL
|
|
echo " [${name}] FAILED (exit ${rc})"
|
|
fi
|
|
}
|
|
|
|
skip_step() {
|
|
local name="$1"
|
|
local reason="$2"
|
|
echo
|
|
echo ">> [${name}] SKIPPED: ${reason}"
|
|
record "${name}" SKIP
|
|
}
|
|
|
|
echo "Phase 0 aggregator — preset='${PRESET}'${BINARY_DIR:+ binaryDir='${BINARY_DIR}'}"
|
|
|
|
# --- 1. Rule R2 boundary -----------------------------------------------------
|
|
run_step 'R2 boundary' bash "${REPO_ROOT}/scripts/check_pdfium_boundary.sh"
|
|
|
|
# --- 2. Engine ---------------------------------------------------------------
|
|
engine_configure() {
|
|
if [[ -n "${BINARY_DIR}" ]]; then cmake --preset "${PRESET}" -B "${BINARY_DIR}";
|
|
else cmake --preset "${PRESET}"; fi
|
|
}
|
|
engine_build() {
|
|
if [[ -n "${BINARY_DIR}" ]]; then cmake --build "${BINARY_DIR}";
|
|
else cmake --build --preset "${PRESET}"; fi
|
|
}
|
|
engine_test() {
|
|
if [[ -n "${BINARY_DIR}" ]]; then ctest --test-dir "${BINARY_DIR}" --output-on-failure;
|
|
else ctest --preset "${PRESET}"; fi
|
|
}
|
|
|
|
if [[ "${SKIP_ENGINE:-0}" == "1" ]]; then
|
|
skip_step 'engine' 'requested via SKIP_ENGINE=1'
|
|
elif [[ -z "${VCPKG_ROOT:-}" ]]; then
|
|
skip_step 'engine' 'VCPKG_ROOT not set — run scripts/bootstrap.sh first (and re-source your shell rc)'
|
|
else
|
|
run_step 'engine configure' engine_configure
|
|
if [[ "${LAST_STATUS}" == PASS ]]; then
|
|
run_step 'engine build' engine_build
|
|
if [[ "${LAST_STATUS}" == PASS ]]; then
|
|
run_step 'engine test' engine_test
|
|
else
|
|
skip_step 'engine test' 'build failed'
|
|
fi
|
|
else
|
|
skip_step 'engine build' 'configure failed'
|
|
skip_step 'engine test' 'configure failed'
|
|
fi
|
|
fi
|
|
|
|
# --- 3. Gateway --------------------------------------------------------------
|
|
PY=""
|
|
if command -v python3 >/dev/null 2>&1; then PY="$(command -v python3)";
|
|
elif command -v python >/dev/null 2>&1; then PY="$(command -v python)"; fi
|
|
|
|
if [[ "${SKIP_GATEWAY:-0}" == "1" ]]; then
|
|
skip_step 'gateway' 'requested via SKIP_GATEWAY=1'
|
|
elif [[ -z "${PY}" ]]; then
|
|
skip_step 'gateway' 'python/python3 not on PATH'
|
|
else
|
|
pushd gateway >/dev/null
|
|
run_step 'gateway install' "${PY}" -m pip install --quiet -e ".[dev]"
|
|
if [[ "${LAST_STATUS}" == PASS ]]; then
|
|
run_step 'gateway lint' "${PY}" -m ruff check .
|
|
run_step 'gateway format' "${PY}" -m ruff format --check .
|
|
run_step 'gateway pytest' "${PY}" -m pytest
|
|
fi
|
|
popd >/dev/null
|
|
fi
|
|
|
|
# --- 4. WASM hello-world -----------------------------------------------------
|
|
if [[ "${SKIP_WASM:-0}" == "1" ]]; then
|
|
skip_step 'wasm' 'requested via SKIP_WASM=1'
|
|
elif ! command -v emcc >/dev/null 2>&1; then
|
|
skip_step 'wasm' 'emcc not on PATH — source emsdk_env.sh first'
|
|
elif ! command -v node >/dev/null 2>&1; then
|
|
skip_step 'wasm' 'node not on PATH'
|
|
else
|
|
run_step 'wasm configure' cmake --preset wasm
|
|
if [[ "${LAST_STATUS}" == PASS ]]; then
|
|
run_step 'wasm build' cmake --build --preset wasm
|
|
if [[ "${LAST_STATUS}" == PASS ]]; then
|
|
run_step 'wasm test' node wasm/hello.test.mjs
|
|
else
|
|
skip_step 'wasm test' 'build failed'
|
|
fi
|
|
else
|
|
skip_step 'wasm build' 'configure failed'
|
|
skip_step 'wasm test' 'configure failed'
|
|
fi
|
|
fi
|
|
|
|
# --- Summary ----------------------------------------------------------------
|
|
echo
|
|
echo '================ Phase 0 summary ================'
|
|
pad=0
|
|
for s in "${STEPS[@]}"; do
|
|
if (( ${#s} > pad )); then pad=${#s}; fi
|
|
done
|
|
any_fail=0
|
|
for i in "${!STEPS[@]}"; do
|
|
printf " %-${pad}s %s\n" "${STEPS[$i]}" "${STATUSES[$i]}"
|
|
if [[ "${STATUSES[$i]}" == FAIL ]]; then any_fail=1; fi
|
|
done
|
|
echo '================================================='
|
|
|
|
if [[ "${any_fail}" -ne 0 ]]; then
|
|
echo 'Phase 0: FAIL'
|
|
exit 1
|
|
fi
|
|
echo 'Phase 0: PASS'
|
|
exit 0
|