ci(ariadne): restore LOC checker with tracked waivers
This commit is contained in:
parent
a57577e2a5
commit
26cc9333c7
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -173,7 +173,7 @@ mkdir -p build
|
||||
set +e
|
||||
python -m pip install --no-cache-dir -r requirements.txt -r requirements-dev.txt \
|
||||
&& python -m ruff check ariadne scripts --select PLR \
|
||||
&& python scripts/check_file_sizes.py --roots ariadne scripts testing --max-lines 500 --waivers ci/loc_hygiene_waivers.tsv \
|
||||
&& python scripts/check_file_sizes.py --roots ariadne scripts tests --max-lines 500 --waivers ci/loc_hygiene_waivers.tsv \
|
||||
&& python -m slipcover \
|
||||
--json \
|
||||
--out "${COVERAGE_JSON}" \
|
||||
|
||||
15
ci/loc_hygiene_waivers.tsv
Normal file
15
ci/loc_hygiene_waivers.tsv
Normal file
@ -0,0 +1,15 @@
|
||||
# path reason
|
||||
ariadne/services/cluster_state.py split planned; service orchestration decomposition tracked in hygiene backlog
|
||||
ariadne/app.py split planned; Flask app bootstrap/routes currently co-located
|
||||
ariadne/services/comms.py split planned; comms adapters still consolidated
|
||||
ariadne/manager/provisioning.py split planned; provisioning flow modules pending extraction
|
||||
ariadne/services/nextcloud.py split planned; provider methods pending partition
|
||||
ariadne/services/firefly.py split planned; provider methods pending partition
|
||||
ariadne/settings.py split planned; settings schema + helpers pending split
|
||||
ariadne/services/jenkins_workspace_cleanup.py split planned; job orchestration pending extraction
|
||||
ariadne/services/wger.py split planned; provider methods pending partition
|
||||
ariadne/services/vault.py split planned; auth + data access helpers pending split
|
||||
tests/test_provisioning.py test module split planned; broad provisioning coverage retained meanwhile
|
||||
tests/test_services.py test module split planned; broad service contract coverage retained meanwhile
|
||||
tests/test_app.py test module split planned; API coverage retained meanwhile
|
||||
tests/test_keycloak_admin.py test module split planned; identity admin coverage retained meanwhile
|
||||
|
85
scripts/check_file_sizes.py
Normal file
85
scripts/check_file_sizes.py
Normal file
@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fail when source files exceed a configured line-count threshold."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
DEFAULT_SKIP_PARTS = {
|
||||
".git",
|
||||
".venv",
|
||||
"venv",
|
||||
"build",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"__pycache__",
|
||||
".pytest_cache",
|
||||
}
|
||||
SOURCE_SUFFIXES = {".py", ".sh", ".json", ".yaml", ".yml"}
|
||||
|
||||
|
||||
def _read_waivers(path: Path) -> set[str]:
|
||||
if not path.exists():
|
||||
return set()
|
||||
waived: set[str] = set()
|
||||
for line in path.read_text(encoding="utf-8").splitlines():
|
||||
row = line.strip()
|
||||
if not row or row.startswith("#"):
|
||||
continue
|
||||
waived.add(row.split("\t", 1)[0].strip())
|
||||
return waived
|
||||
|
||||
|
||||
def _iter_files(root: Path) -> list[Path]:
|
||||
if not root.exists():
|
||||
return []
|
||||
files: list[Path] = []
|
||||
for path in root.rglob("*"):
|
||||
if not path.is_file():
|
||||
continue
|
||||
if any(part in DEFAULT_SKIP_PARTS for part in path.parts):
|
||||
continue
|
||||
if path.suffix.lower() not in SOURCE_SUFFIXES and path.name != "Jenkinsfile":
|
||||
continue
|
||||
files.append(path)
|
||||
return files
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--roots", nargs="+", required=True)
|
||||
parser.add_argument("--max-lines", type=int, default=500)
|
||||
parser.add_argument("--waivers", default="ci/loc_hygiene_waivers.tsv")
|
||||
args = parser.parse_args()
|
||||
|
||||
repo_root = Path.cwd().resolve()
|
||||
waived = _read_waivers(repo_root / args.waivers)
|
||||
|
||||
offenders: list[tuple[int, str]] = []
|
||||
for root_name in args.roots:
|
||||
for path in _iter_files(repo_root / root_name):
|
||||
rel = path.relative_to(repo_root).as_posix()
|
||||
if rel in waived:
|
||||
continue
|
||||
try:
|
||||
line_count = sum(1 for _ in path.open("r", encoding="utf-8", errors="ignore"))
|
||||
except OSError:
|
||||
continue
|
||||
if line_count > args.max_lines:
|
||||
offenders.append((line_count, rel))
|
||||
|
||||
if not offenders:
|
||||
print(f"[loc] ok: no files exceed {args.max_lines} lines")
|
||||
return 0
|
||||
|
||||
offenders.sort(reverse=True)
|
||||
print(f"[loc] failed: {len(offenders)} file(s) exceed {args.max_lines} lines")
|
||||
for lines, rel in offenders:
|
||||
print(f" - {rel}: {lines} lines")
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Loading…
x
Reference in New Issue
Block a user