Files
ConformalLabpp/scripts/quality/README.md
Tarik Moussa 1aa3493e7d
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 1m57s
API Docs / doc-build (pull_request) Successful in 48s
Markdown link check / check (pull_request) Successful in 51s
C++ Tests / test-cgal (pull_request) Failing after 12m23s
quality: 4 more gates + dependency audit; full --fast sweep 10/10 green
This commit closes the structural-tests work on PR #18.  Every gate
in `run-all.sh --fast` now passes end-to-end on the canonical dev
machine.

New gates
─────────
1. shellcheck (scripts/quality/shellcheck.sh)
   * Scans every `scripts/**/*.sh` at severity=warning+
   * 16 scripts inspected; cleanup pass took the tree from 7 findings
     (SC2164 + SC2034) to 0 findings.

2. cppcheck (scripts/quality/cppcheck.sh)
   * Complementary static analyser to clang-tidy; different heuristics,
     fewer false-positives on heavy CGAL/Eigen templates.
   * Default severity warning+, --strict adds style, --all = everything.
   * Suppresses 4 noise classes (missingIncludeSystem, etc.) explicitly.

3. .editorconfig
   * Cross-IDE fallback for editors that don't honour clang-format.
   * Covers Markdown (preserve trailing whitespace), Python, YAML,
     JSON, shell, Makefile (tabs) — the file types clang-format
     doesn't cover.

4. CONFORMALLAB_WARNINGS_AS_ERRORS CMake option
   * Off by default → regular builds don't break on new GCC warnings.
   * `-DCONFORMALLAB_WARNINGS_AS_ERRORS=ON` adds `-Werror`, intended for
     CI promotion-track and sanitizer runs.

Dependency audit  (doc/architecture/dependencies.md)
────────────────────────────────────────────────────
New single-source-of-truth document listing:
  * what the library requires (Eigen + CGAL + Boost — all header-only)
  * what tests require (auto-fetched GTest, no system install)
  * what each quality tool is for, install command per OS, and
    behaviour when missing (each gate exits 2 = SKIP, run-all
    recognises this and continues)
  * a verification recipe that strips PATH down and shows the
    library still configures + builds + tests cleanly with zero
    quality tools installed.

run-all.sh enhanced
───────────────────
* Recognises "tool not in PATH" → SKIP (not FAIL).
* Summary now reports `passed / skipped / failed` separately.

Bug fixes uncovered by the sweep
────────────────────────────────
* sanitizers.sh: gtest_discover_tests ran the ASan-instrumented
  binary at build time and aborted → added
  `-DCMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE=PRE_TEST` to defer
  discovery to ctest invocation.  Now 23/23 sanitizer-instrumented
  tests pass.

* clang-tidy.sh on macOS: brew-installed clang-tidy couldn't find
  Apple SDK system headers (<cmath>, <complex>, …) → added
  `--extra-arg=-isysroot $(xcrun --show-sdk-path)` on Darwin.

* clang-tidy.sh: needed `-DWITH_CGAL_TESTS=ON` in compile_commands
  generation so CGAL include paths are part of at least one
  compile entry.  Now resolves CGAL/Surface_mesh.h etc.

* clang-tidy.sh: viewer-only headers (`viewer_utils.h`, `mesh_utils.hpp`)
  excluded — they need `WITH_VIEWER=ON` + system GLFW/libigl that the
  lint build doesn't drag in.

* `.codespellrc`: extended ignore list (recognise, signalled, modelled,
  travelled, …) for British-English consistency across own writing.

Final state — local quality block on this commit, this branch:

     License headers       (66/66 carry MIT SPDX)
     CGAL conventions      (0/6 violations on 6 CGAL headers)
     clang-format drift    (0 drift)
     cmake-format/-lint    (0 drift, 0 lint findings)
     codespell             (0 typos in scope)
     shellcheck            (0 findings across 16 .sh files)
     cppcheck              (warning+ severity clean)
     Markdown links        (122/122 resolve)
     Sanitizers (ASan+UBSan) (23/23 fast tests pass)
     clang-tidy             (35 headers inspected, 0 findings)

Library standalone-ness verified:
    env -i PATH=... cmake -S code -B /tmp/build-standalone
    cmake --build /tmp/build-standalone --target conformallab_tests
    ctest -E '^cgal\.'    →  all green

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 09:56:40 +02:00

89 lines
4.4 KiB
Markdown
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.

# Local structural quality gates
This directory contains the structural quality checks that run **locally**
rather than in CI. They are intentionally not wired into
`.gitea/workflows/` (yet) because each is either too slow, too brittle
against the runner environment, or both — running them before a release
or before showing the repo to an external reviewer is the intended
workflow.
The CI gates that *are* enforced live in `.gitea/workflows/cpp-tests.yml`
and `.gitea/workflows/doxygen-pages.yml`; they cover the day-to-day
correctness loop (build + test + doxygen-coverage + test-count
consistency + markdown links + end-to-end smoke via `try_it.sh`).
## What runs locally
### Style / convention gates (run on every commit; cheap)
| Script | What it checks | Wall time | Prereqs |
|---|---|---|---|
| `license-headers.sh` | every C++ source carries `SPDX-License-Identifier: MIT` | ~1 s | `bash` |
| `cgal-conventions.py` | CGAL-1…6: include-guard format, `\file` brief, namespace nesting, tag-naming, no `using namespace`, no stray `#define` | ~1 s | `python3` |
| `clang-format.sh` | every C++ source matches `.clang-format` (dry-run by default; `--fix` to apply) | ~2 s | `clang-format` ≥ 15 |
| `cmake-format.sh` | every `CMakeLists.txt` matches `.cmake-format.yaml` + passes `cmake-lint` | ~2 s | `cmake-format` (pip: cmakelang) |
| `codespell.sh` | typo check across docs + source comments + script messages | ~1 s | `codespell` |
| `shellcheck.sh` | static analysis of every `scripts/**/*.sh` | ~1 s | `shellcheck` |
| `cppcheck.sh` | second-opinion static analyser over `code/include/` | ~5 s | `cppcheck` |
| `../check-markdown-links.py` | every internal markdown link resolves | ~2 s | `python3` |
### Correctness / quality gates (run before tagging or reviewer demos)
| Script | What it checks | Wall time | Prereqs |
|---|---|---|---|
| `sanitizers.sh` | fast test suite under ASan + UBSan | ~3 min | `clang++` ≥ 14 or `g++` ≥ 11 |
| `coverage.sh` | gcov/lcov line + branch coverage of `code/include/` | ~2 min | `lcov` |
| `clang-tidy.sh` | curated clang-tidy checks over public headers | ~2 min | `clang-tidy` ≥ 14, `.clang-tidy` |
| `multi-compiler.sh` | build + test under every detected gcc/clang | ~5 min × N compilers | any 2 of `g++`, `clang++` |
| `reproducible-build.sh` | two builds → byte-identical test executables | ~6 min | none beyond compiler |
| `cgal-version-matrix.sh` | build + CGAL test suite against multiple CGAL versions | ~5 min × N versions | CGAL trees under `~/cgal/<ver>/` (or `CGAL_ROOTS=...`) |
## How to use
```bash
# Fast subset (license + links + sanitizers + clang-tidy) — ~5 min total
bash scripts/quality/run-all.sh --fast
# Full sweep — ~2540 min, intended for pre-release tagging
bash scripts/quality/run-all.sh
# One specific gate
bash scripts/quality/sanitizers.sh
```
Every gate writes its full output to `build-quality-logs/<gate>.log`
when invoked via `run-all.sh`, and to its own per-gate build directory
(`build-sanitizers/`, `build-coverage/`, `build-multi-<cc>/`, …) when
invoked directly.
## Promotion path to CI
Each gate can be wired into `.gitea/workflows/cpp-tests.yml` once two
conditions are met:
1. **The gate is green on the canonical dev machine.** If the script
exits 1 today, the CI gate would block every PR.
2. **There is a published policy line in `doc/release-policy.md`** that
explains what regression the gate catches and what the recovery is.
Future contributors should be able to read the error and know what
to fix.
Promoting a gate is a one-line change to `cpp-tests.yml`; the test
recipe is the script invocation itself.
## Known limitations
- `cgal-version-matrix.sh` does not download CGAL. Each version must
already be on the dev machine under `~/cgal/<ver>/` (override with
`CGAL_ROOTS=...:...`). The Dockerfile under
`.gitea/docker/Dockerfile.ci-cpp` could be extended to ship multiple
CGAL trees in a single image; not done yet.
- `sanitizers.sh` only instruments the fast (non-CGAL) test suite —
the CGAL templates are too expensive to compile under instrumentation
on most laptops.
- `clang-tidy.sh` requires a `.clang-tidy` config in the repo root; the
default Anthropic-quality lint set is intentionally minimal until the
reviewer signs off on the warning policy.
- `reproducible-build.sh` checks the test executables only. The
library is header-only, so there is nothing else to compare.