From 38444404d135fe0eb8c3de60868eda236b72f701 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Wed, 21 Oct 2026 05:08:00 +0200 Subject: [PATCH] fix: surface data rows that name no registry key The buildbot system row was planned as refresh_data_dirs.py --key 'buildbot system', which always exits 1 on an unknown key. A data row now runs only when its subject is a _data_dirs.yml entry; the rest is shown for a human to add. --- scripts/refresh_stale.py | 19 ++++++++++++++++--- tests/test_refresh_stale.py | 10 ++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/scripts/refresh_stale.py b/scripts/refresh_stale.py index 8712b101..d83f8828 100755 --- a/scripts/refresh_stale.py +++ b/scripts/refresh_stale.py @@ -25,7 +25,8 @@ Mapping (stale -> command): catalogs/fbneo recipes python -m scripts.scraper.romset_dat_importer --source fbneo --fetch -Surfaced only (no refresh): coreinfo gaps, redump/no-intro/tosec packs, +Surfaced only (no refresh): data rows that are not a _data_dirs.yml key +(the registry itself, buildbot assets it does not track), coreinfo gaps, redump/no-intro/tosec packs, CI pins (install.py SHA-256, PyPI, pinned actions), profile_sync. Each needs a human read (new .info file, manual DAT download, PyPI version bump). @@ -46,12 +47,14 @@ import sys import time from concurrent.futures import ThreadPoolExecutor, as_completed from dataclasses import dataclass +from functools import lru_cache from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] LOG_DIR = REPO_ROOT / "tmp" / "refresh_stale" CHECK_FRESHNESS = REPO_ROOT / "scripts" / "check_freshness.py" PLATFORMS_REGISTRY = REPO_ROOT / "platforms" / "_registry.yml" +DATA_DIRS_REGISTRY = REPO_ROOT / "platforms" / "_data_dirs.yml" AUTO_AREAS = ("platforms", "native", "targets", "data", "catalogs") MANUAL_AREAS = ("coreinfo", "ci", "profiles") @@ -91,6 +94,15 @@ def _load_platform_registry() -> dict[str, dict]: return (yaml.safe_load(fh) or {}).get("platforms") or {} +@lru_cache(maxsize=1) +def _data_dir_keys() -> frozenset[str]: + """The entries refresh_data_dirs.py --key accepts.""" + import yaml + + with DATA_DIRS_REGISTRY.open(encoding="utf-8") as fh: + return frozenset((yaml.safe_load(fh) or {}).get("data_directories") or {}) + + def _run_check_freshness(areas: tuple[str, ...], extra: list[str]) -> list[dict]: """Run check_freshness.py --json and return its findings.""" cmd = [sys.executable, str(CHECK_FRESHNESS), "--json"] @@ -246,8 +258,9 @@ def _command_for( ] if area == "data": - if subject == "_data_dirs.yml": - # The registry file itself cannot be refreshed, but its entries can. + if subject not in _data_dir_keys(): + # "_data_dirs.yml" and "buildbot system" name the registry and + # what it does not track yet: a human adds the entry. return None return [ sys.executable, diff --git a/tests/test_refresh_stale.py b/tests/test_refresh_stale.py index 691f9f9a..3b7b01eb 100644 --- a/tests/test_refresh_stale.py +++ b/tests/test_refresh_stale.py @@ -101,6 +101,16 @@ class Planning(unittest.TestCase): ) self.assertEqual([f["subject"] for f in surfaced], ["redump"]) + def test_a_data_row_outside_the_registry_needs_a_human(self): + """refresh_data_dirs.py --key 'buildbot system' exits 1 on an unknown + key: the row asks for a registry entry, not a refresh.""" + jobs, surfaced, _ = self._plan( + finding("data", "buildbot system"), finding("data", "_data_dirs.yml") + ) + self.assertEqual(jobs, []) + self.assertEqual([f["subject"] for f in surfaced], + ["buildbot system", "_data_dirs.yml"]) + def test_only_stale_rows_run_and_errors_are_shown(self): jobs, surfaced, ignored = self._plan( finding("data", "a", "OK"),