Files
ConformalLabpp/scripts/quality/run-all.sh
Tarik Moussa f1d77aa293
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 2m26s
API Docs / doc-build (pull_request) Successful in 55s
Markdown link check / check (pull_request) Successful in 49s
C++ Tests / test-cgal (pull_request) Failing after 12m24s
quality: add code-style + CGAL-convention checkers (local-only)
Closes the gap "no code-quality / convention gate" from the structural
review.  Three new artefacts, all local-only (CI promotion deferred
until the existing tree is 100 % clean under each):

1. .clang-format — project's existing style mechanically captured
   (4-space indent, opening brace on new line for class/struct/function,
   left-aligned pointer/reference modifiers, aligned `using = ...` blocks,
   100-col loose limit, no include re-ordering — matches code/include/
   today).

2. scripts/quality/clang-format.sh — drift detector.  Dry-run mode by
   default (always exits 0); --strict to fail on drift; --fix to apply
   suggested changes in place.  Skips code/deps/ and macOS-duplicate
   files.

3. scripts/quality/cgal-conventions.py — checker for the CGAL idioms
   that clang-format/clang-tidy cannot express:
     CGAL-1  include-guard format `CGAL_<DIRS>_<FILE>_H`
     CGAL-2  every public header has a `\\file` Doxygen brief
     CGAL-3  no nested namespaces beyond the allowed set
             (CGAL::parameters, CGAL::Conformal_map, internal_np, IO)
     CGAL-4  named-parameter tag types end in `_t`; value object does not
     CGAL-5  no `using namespace ...` at file scope (header leakage)
     CGAL-6  no #define beyond CGAL_* / include-guard

   Result on the current tree: 6 CGAL public headers, 0 violations.
   The checker therefore doubles as documentation of the conventions
   we already follow.

Both are wired into scripts/quality/run-all.sh's fast subset (~5 s
combined wall time).  README.md updated to split the gates into a
"style/convention" group (cheap, run-on-every-commit material) and a
"correctness/quality" group (slow, run-before-tag material).

The reviewer-facing locked-vs-flexible.md gains another " Closed"
row documenting both gates and the 0-violation baseline.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 08:37:12 +02:00

103 lines
3.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 ~2540 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"
"CGAL conventions | python3 scripts/quality/cgal-conventions.py"
"clang-format drift | bash scripts/quality/clang-format.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