#requires -Version 5.1 # 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.ps1) # 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. # # Examples: # pwsh scripts/test_phase0.ps1 # pwsh scripts/test_phase0.ps1 -Preset win-local-pdfium # pwsh scripts/test_phase0.ps1 -BinaryDir C:/Users/me/pdfeng-build/windows-debug # pwsh scripts/test_phase0.ps1 -SkipWasm # # OneDrive note: on this repo's spaced/OneDrive-synced path the default in-tree # binaryDir breaks the engine build (see docs/phase0.md "OneDrive warning"). # Pass -BinaryDir to redirect, or use a CMakeUserPresets preset that already # does so (e.g. win-local-pdfium). param( [string]$Preset = '', [string]$BinaryDir = '', [switch]$SkipEngine, [switch]$SkipGateway, [switch]$SkipWasm ) $ErrorActionPreference = 'Continue' $RepoRoot = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path) Set-Location $RepoRoot if (-not $Preset) { if ($env:OS -eq 'Windows_NT') { $Preset = 'windows-debug' } elseif ($IsMacOS) { $Preset = 'macos-debug' } else { $Preset = 'linux-debug' } } $script:results = [ordered]@{} function Invoke-Step { param([string]$Name, [scriptblock]$Body) Write-Host '' Write-Host ">> [$Name]" $global:LASTEXITCODE = 0 try { & $Body $rc = $LASTEXITCODE if ($rc -and $rc -ne 0) { $script:results[$Name] = 'FAIL' Write-Host " [$Name] FAILED (exit $rc)" } else { $script:results[$Name] = 'PASS' Write-Host " [$Name] OK" } } catch { $script:results[$Name] = 'FAIL' Write-Host " [$Name] FAILED: $_" } } function Skip-Step { param([string]$Name, [string]$Reason) Write-Host '' Write-Host ">> [$Name] SKIPPED: $Reason" $script:results[$Name] = 'SKIP' } Write-Host "Phase 0 aggregator - preset='$Preset'$(if ($BinaryDir) { " binaryDir='$BinaryDir'" })" # --- 1. Rule R2 boundary ----------------------------------------------------- Invoke-Step 'R2 boundary' { & (Join-Path $RepoRoot 'scripts/check_pdfium_boundary.ps1') } # --- 2. Engine --------------------------------------------------------------- if ($SkipEngine) { Skip-Step 'engine' 'requested via -SkipEngine' } elseif (-not $env:VCPKG_ROOT) { Skip-Step 'engine' 'VCPKG_ROOT not set - run scripts/bootstrap.ps1 first (and re-open the shell, or set $env:VCPKG_ROOT)' } else { Invoke-Step 'engine configure' { if ($BinaryDir) { cmake --preset $Preset -B $BinaryDir } else { cmake --preset $Preset } } if ($script:results['engine configure'] -eq 'PASS') { Invoke-Step 'engine build' { if ($BinaryDir) { cmake --build $BinaryDir } else { cmake --build --preset $Preset } } if ($script:results['engine build'] -eq 'PASS') { Invoke-Step 'engine test' { if ($BinaryDir) { ctest --test-dir $BinaryDir --output-on-failure } else { ctest --preset $Preset } } } else { Skip-Step 'engine test' 'build failed' } } else { Skip-Step 'engine build' 'configure failed' Skip-Step 'engine test' 'configure failed' } } # --- 3. Gateway -------------------------------------------------------------- if ($SkipGateway) { Skip-Step 'gateway' 'requested via -SkipGateway' } elseif (-not (Get-Command python -ErrorAction SilentlyContinue)) { Skip-Step 'gateway' 'python not found on PATH' } else { Push-Location (Join-Path $RepoRoot 'gateway') try { Invoke-Step 'gateway install' { python -m pip install --quiet -e ".[dev]" } if ($script:results['gateway install'] -eq 'PASS') { Invoke-Step 'gateway lint' { python -m ruff check . } Invoke-Step 'gateway format' { python -m ruff format --check . } Invoke-Step 'gateway pytest' { python -m pytest } } } finally { Pop-Location } } # --- 4. WASM hello-world ----------------------------------------------------- if ($SkipWasm) { Skip-Step 'wasm' 'requested via -SkipWasm' } elseif (-not (Get-Command emcc -ErrorAction SilentlyContinue)) { Skip-Step 'wasm' 'emcc not on PATH - activate emsdk (emsdk_env.ps1) first' } elseif (-not (Get-Command node -ErrorAction SilentlyContinue)) { Skip-Step 'wasm' 'node not on PATH' } else { Invoke-Step 'wasm configure' { cmake --preset wasm } if ($script:results['wasm configure'] -eq 'PASS') { Invoke-Step 'wasm build' { cmake --build --preset wasm } if ($script:results['wasm build'] -eq 'PASS') { Invoke-Step 'wasm test' { node wasm/hello.test.mjs } } else { Skip-Step 'wasm test' 'build failed' } } else { Skip-Step 'wasm build' 'configure failed' Skip-Step 'wasm test' 'configure failed' } } # --- Summary ---------------------------------------------------------------- Write-Host '' Write-Host '================ Phase 0 summary ================' $pad = 0 foreach ($k in $script:results.Keys) { if ($k.Length -gt $pad) { $pad = $k.Length } } $fmt = ' {0,-' + $pad + '} {1}' $anyFail = $false foreach ($name in $script:results.Keys) { $status = $script:results[$name] Write-Host ($fmt -f $name, $status) if ($status -eq 'FAIL') { $anyFail = $true } } Write-Host '=================================================' if ($anyFail) { Write-Host 'Phase 0: FAIL' exit 1 } Write-Host 'Phase 0: PASS' exit 0