added filter to decide what challenges to include

This commit is contained in:
2026-11-05 15:42:52 +01:00
parent 4fac6ed86d
commit 09849d0ef6
11 changed files with 214 additions and 28 deletions
+43
View File
@@ -0,0 +1,43 @@
"""challenges.yml: which repos are part of this CTF, and their check exceptions."""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
import yaml
from .challenge import SELECTIONS
from .checks import REPO_CHECKS
SELECTION_FILE = Path(__file__).parent.parent / "challenges.yml" # next to ctf_status.py
@dataclass
class Selection:
states: dict # repo path -> one of SELECTIONS
skip_checks: dict # repo path -> names of REPO_CHECKS it need not pass
def load_selection(path: Path = SELECTION_FILE) -> Selection:
"""Raises ValueError on anything off. A broken file must stop the run: without
it nothing counts as included, and challs.txt would be committed empty."""
try:
doc = yaml.safe_load(path.read_text())
except (OSError, yaml.YAMLError) as e:
raise ValueError(f"cannot read {path.name}: {e}") from None
states = doc.get("challenges") if isinstance(doc, dict) else None
if not states or not isinstance(states, dict):
raise ValueError(f"{path.name} has no `challenges:` mapping")
bad = [f"{k}: {v}" for k, v in states.items() if v not in SELECTIONS]
if bad:
raise ValueError(f"{path.name}: expected one of {', '.join(SELECTIONS)}, got " + ", ".join(bad))
skip = doc.get("skip_checks") or {}
if not isinstance(skip, dict) or not all(isinstance(v, list) for v in skip.values()):
raise ValueError(f"{path.name}: `skip_checks:` must map repos to lists of checks")
known = {check.__name__ for check in REPO_CHECKS}
bad = sorted({str(n) for names in skip.values() for n in names} - known)
if bad:
raise ValueError(f"{path.name}: no such repo check: " + ", ".join(bad))
return Selection({str(k): v for k, v in states.items()},
{str(k): [str(n) for n in v] for k, v in skip.items()})