fix: create scratch dir and scope catalog ratio

This commit is contained in:
Abdessamad Derraz committed 2026-08-08 11:05:23 +02:00
1 parent b26a874966
commit eb2c064518
4 files changed
+62 -13

No files matched your search

+3
View File
@@ -1672,6 +1672,9 @@ def _normalize_zip_for_pack(
"""
import tempfile as _tmp
# tmp/ is gitignored, so a fresh clone does not carry it. WSL keeps /tmp
# on a 4 GB tmpfs that MAME sets overflow, hence the repo-local scratch.
os.makedirs("tmp", exist_ok=True)
tmp_fd, tmp_path = _tmp.mkstemp(suffix=".zip", dir="tmp")
os.close(tmp_fd)
try:
+19 -4
View File
@@ -18,6 +18,7 @@ from datetime import datetime, timezone
sys.path.insert(0, os.path.dirname(__file__))
from common import (
GAME_DATA_TOPS,
compute_composition,
list_registered_platforms,
load_database,
@@ -154,18 +155,32 @@ _CATALOG_LABELS = {"redump": "Redump", "no-intro": "No-Intro", "tosec": "TOSEC"}
def _catalog_matched_line(db: dict) -> list[str]:
"""Bullet line for files matched to dump-preservation catalogs."""
"""Bullet line for files matched to dump-preservation catalogs.
Counted against the system files alone: those catalogs index console and
computer dumps, so arcade ROM sets and engine data sit outside their
scope and would only dilute the ratio.
"""
sources: set[str] = set()
matched = 0
for entry in db.get("files", {}).values():
provenance = entry.get("provenance")
if provenance:
if not provenance:
continue
sources.update(provenance)
parts = entry.get("path", "").split("/")
top = parts[1] if len(parts) > 1 else ""
if top != "Arcade" and top not in GAME_DATA_TOPS:
matched += 1
sources.update(provenance)
if not matched:
return []
system_files = compute_composition(db)["systems"]["files"]
labels = ", ".join(_CATALOG_LABELS.get(s, s) for s in sorted(sources))
return [f"- **{matched:,} files** matched to dump-preservation catalogs ({labels})"]
return [
f"- **{matched:,} of {system_files:,} system files** matched to"
f" dump-preservation catalogs ({labels}); arcade sets and engine data"
f" fall outside what those catalogs index"
]
def generate_readme(db: dict, platforms_dir: str) -> str:
+31
View File
@@ -54,6 +54,35 @@ ICON_CACHE_PATH = Path(".cache") / "system_icons.json"
_icon_available: dict[str, bool] = {}
def _content_check_ceiling(profiles: dict) -> str:
"""How far content checking can reach across every profiled entry."""
hashed = sized = neither = 0
for profile in unique_emulator_profiles(profiles).values():
for f in profile.get("files", []) or []:
if any(
f.get(k)
for k in ("md5", "sha1", "crc32", "sha256", "known_hash_adler32")
):
hashed += 1
elif any(f.get(k) for k in ("size", "min_size", "max_size")):
sized += 1
else:
neither += 1
total = hashed + sized + neither
if not total:
return ""
return (
f"Across every profiled entry, {hashed:,} of {total:,} "
f"({hashed / total * 100:.0f}%) carry a hash the code checks, "
f"{sized:,} ({sized / total * 100:.0f}%) only a size, and "
f"{neither:,} ({neither / total * 100:.0f}%) neither. That last share "
"is the ceiling of the method: where an emulator validates nothing, "
"reading its source establishes which file it loads, never whether "
"the content is the right dump. The provenance field answers that "
"other question, for the files a dump catalog indexes."
)
def _icon_name(manufacturer: str, console_name: str) -> str:
return f"{manufacturer} - {console_name}".replace("/", " ")
@@ -1884,6 +1913,8 @@ def generate_gap_analysis(
"profiled emulator applies to the platform, whose own source is then "
"the only authority.",
"",
_content_check_ceiling(profiles),
"",
])
# ---- Section 1b: platform lists vs emulator source ----