added filter to decide what challenges to include
This commit is contained in:
@@ -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()})
|
||||
Reference in New Issue
Block a user