#!/usr/bin/env python3 # Copyright (c) 2025-2026, RTE (https://www.rte-france.com) # This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0. # If a copy of the Mozilla Public License, version 2.0 was not distributed with this file, # you can obtain one at http://mozilla.org/MPL/2.0/. # SPDX-License-Identifier: MPL-2.0 """Gate pull requests on code-quality thresholds. Exits non-zero when any threshold is violated. The numbers encode the reductions won in `docs/architecture/code-quality-analysis.md` and are intentionally a ceiling, not a target — lowering them is welcome, raising them is a regression. Thresholds (see also CONTRIBUTING.md): | Metric | Max | |----------------------------------------------|-------| | `print(` calls in backend sources | 0 | | `traceback.print_exc()` calls in backend | 0 | | Bare `except Exception: pass` patterns | 0 | | Backend module size (lines) | 1150 | | Backend function size (lines) | 240 | | Backend function cyclomatic complexity | 38 | | Backend function nesting depth | 8 | | `noqa` / `type: ignore` markers (ratchet) | 3 | | Backend functions missing return ann (ratchet)| 60 | | Frontend component size (lines) | 1450 | | `frontend/src/utils/**` module size (lines) | 1000 | | `App.tsx` hub size (lines) | 2100 | | `any` / `as any` annotations in frontend | 0 | | `@ts-ignore` / `-expect-error` / `-nocheck` | 0 | | `as unknown as` casts (ratchet) | 12 | | `Record` usages (ratchet) | 45 | | Hex color literals outside tokens.{css,ts} | 0 | Scope: the backend scan now covers ALL of `expert_backend/` except the `tests/` suite, the ad-hoc `test_backend.py`, and the setup-time `install_graphviz.py` — previously only `main.py` + `services/` were scanned, leaving the whole `recommenders/` package ungated. `App.tsx` is the state-orchestration hub by design, but "by design" is not a blank cheque: it gets a generous *bounded* ceiling (`APP_TSX_MAX`) rather than a blanket exemption, so unbounded growth still trips the gate. `tokens.css` / `tokens.ts` are the token-source-of-truth files, exempt from the hex-literal count. Two kinds of allowance, kept deliberately small: * Per-function exemptions — the iframe-overlay template f-string and the lxml geo-layout transform (size + complexity), and `sanitize_for_json` (nesting — its depth is the recursion shape). New offenders are not welcome. * Ratchets — `as unknown as`, `Record`, and backend lint suppressions exist today in non-trivial, often-legitimate counts. The gate FREEZES them at the current level (lowering is welcome; raising is a regression) instead of forcing a big-bang cleanup. The hex-literal ceiling is now zero — every colour in frontend source must come from a named token in `frontend/src/styles/tokens.{css,ts}`. Adding a new colour means defining it in tokens first, then importing it; raising this ceiling is a regression. """ from __future__ import annotations import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) from code_quality_report import build_report # type: ignore[import-not-found] BACKEND_MODULE_MAX = 1150 BACKEND_FUNCTION_MAX = 240 FRONTEND_COMPONENT_MAX = 1450 FRONTEND_UTIL_MAX = 1000 # Functions exempt from `BACKEND_FUNCTION_MAX`. The first is a # template f-string that produces the iframe overlay's