chore: lint and format entire codebase

Run ruff check --fix: remove unused imports (F401), fix f-strings
without placeholders (F541), remove unused variables (F841), fix
duplicate dict key (F601).

Run isort --profile black: normalize import ordering across all files.

Run ruff format: apply consistent formatting (black-compatible) to
all 58 Python files.

3 intentional E402 remain (imports after require_yaml() must execute
after yaml is available).
This commit is contained in:
Abdessamad Derraz
2026-04-01 13:17:55 +02:00
parent a2d30557e4
commit 0a272dc4e9
56 changed files with 5115 additions and 2679 deletions

View File

@@ -18,15 +18,29 @@ from datetime import datetime, timezone
from pathlib import Path
sys.path.insert(0, os.path.dirname(__file__))
from common import list_registered_platforms, load_database, load_platform_config, write_if_changed
from common import (
list_registered_platforms,
load_database,
load_platform_config,
write_if_changed,
)
from verify import verify_platform
def compute_coverage(platform_name: str, platforms_dir: str, db: dict,
data_registry: dict | None = None,
supplemental_names: set[str] | None = None) -> dict:
def compute_coverage(
platform_name: str,
platforms_dir: str,
db: dict,
data_registry: dict | None = None,
supplemental_names: set[str] | None = None,
) -> dict:
config = load_platform_config(platform_name, platforms_dir)
result = verify_platform(config, db, data_dir_registry=data_registry,
supplemental_names=supplemental_names)
result = verify_platform(
config,
db,
data_dir_registry=data_registry,
supplemental_names=supplemental_names,
)
sc = result.get("status_counts", {})
ok = sc.get("ok", 0)
untested = sc.get("untested", 0)
@@ -55,8 +69,9 @@ REPO = "Abdess/retrobios"
def fetch_contributors() -> list[dict]:
"""Fetch contributors from GitHub API, exclude bots."""
import urllib.request
import urllib.error
import urllib.request
url = f"https://api.github.com/repos/{REPO}/contributors"
headers = {"User-Agent": "retrobios-readme/1.0"}
token = os.environ.get("GITHUB_TOKEN", "")
@@ -68,7 +83,8 @@ def fetch_contributors() -> list[dict]:
data = json.loads(resp.read().decode())
owner = REPO.split("/")[0]
return [
c for c in data
c
for c in data
if not c.get("login", "").endswith("[bot]")
and c.get("type") == "User"
and c.get("login") != owner
@@ -87,21 +103,28 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
from common import load_data_dir_registry
from cross_reference import _build_supplemental_index
data_registry = load_data_dir_registry(platforms_dir)
suppl_names = _build_supplemental_index()
coverages = {}
for name in platform_names:
try:
coverages[name] = compute_coverage(name, platforms_dir, db,
data_registry, suppl_names)
coverages[name] = compute_coverage(
name, platforms_dir, db, data_registry, suppl_names
)
except FileNotFoundError:
pass
emulator_count = sum(
1 for f in Path("emulators").glob("*.yml")
if not f.name.endswith(".old.yml")
) if Path("emulators").exists() else 0
emulator_count = (
sum(
1
for f in Path("emulators").glob("*.yml")
if not f.name.endswith(".old.yml")
)
if Path("emulators").exists()
else 0
)
# Count systems from emulator profiles
system_ids: set[str] = set()
@@ -109,6 +132,7 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
if emu_dir.exists():
try:
import yaml
for f in emu_dir.glob("*.yml"):
if f.name.endswith(".old.yml"):
continue
@@ -122,8 +146,12 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
"# RetroBIOS",
"",
f"Complete BIOS and firmware packs for "
f"{', '.join(c['platform'] for c in sorted(coverages.values(), key=lambda x: x['platform'])[:-1])}"
f", and {sorted(coverages.values(), key=lambda x: x['platform'])[-1]['platform']}.",
f"{', '.join(c['platform'] for c in sorted(coverages.values(), key=lambda x: x[
'platform'
])[:-1])}"
f", and {sorted(coverages.values(), key=lambda x: x[
'platform'
])[-1]['platform']}.",
"",
f"**{total_files:,}** verified files across **{len(system_ids)}** systems,"
f" ready to extract into your emulator's BIOS directory.",
@@ -170,48 +198,78 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
display = cov["platform"]
path = extract_paths.get(display, "")
lines.append(
f"| {display} | {cov['total']} | {path} | "
f"[Download]({RELEASE_URL}) |"
f"| {display} | {cov['total']} | {path} | [Download]({RELEASE_URL}) |"
)
lines.extend([
"",
"## What's included",
"",
"BIOS, firmware, and system files for consoles from Atari to PlayStation 3.",
f"Each file is checked against the emulator's source code to match what the"
f" code actually loads at runtime.",
"",
f"- **{len(coverages)} platforms** supported with platform-specific verification",
f"- **{emulator_count} emulators** profiled from source (RetroArch cores + standalone)",
f"- **{len(system_ids)} systems** covered (NES, SNES, PlayStation, Saturn, Dreamcast, ...)",
f"- **{total_files:,} files** verified with MD5, SHA1, CRC32 checksums",
f"- **{size_mb:.0f} MB** total collection size",
"",
"## Supported systems",
"",
])
lines.extend(
[
"",
"## What's included",
"",
"BIOS, firmware, and system files for consoles from Atari to PlayStation 3.",
"Each file is checked against the emulator's source code to match what the"
" code actually loads at runtime.",
"",
f"- **{len(coverages)} platforms** supported with platform-specific verification",
f"- **{emulator_count} emulators** profiled from source (RetroArch cores + standalone)",
f"- **{len(system_ids)} systems** covered (NES, SNES, PlayStation, Saturn, Dreamcast, ...)",
f"- **{total_files:,} files** verified with MD5, SHA1, CRC32 checksums",
f"- **{size_mb:.0f} MB** total collection size",
"",
"## Supported systems",
"",
]
)
# Show well-known systems for SEO, link to full list
well_known = [
"NES", "SNES", "Nintendo 64", "GameCube", "Wii", "Game Boy", "Game Boy Advance",
"Nintendo DS", "Nintendo 3DS", "Switch",
"PlayStation", "PlayStation 2", "PlayStation 3", "PSP", "PS Vita",
"Mega Drive", "Saturn", "Dreamcast", "Game Gear", "Master System",
"Neo Geo", "Atari 2600", "Atari 7800", "Atari Lynx", "Atari ST",
"MSX", "PC Engine", "TurboGrafx-16", "ColecoVision", "Intellivision",
"Commodore 64", "Amiga", "ZX Spectrum", "Arcade (MAME)",
"NES",
"SNES",
"Nintendo 64",
"GameCube",
"Wii",
"Game Boy",
"Game Boy Advance",
"Nintendo DS",
"Nintendo 3DS",
"Switch",
"PlayStation",
"PlayStation 2",
"PlayStation 3",
"PSP",
"PS Vita",
"Mega Drive",
"Saturn",
"Dreamcast",
"Game Gear",
"Master System",
"Neo Geo",
"Atari 2600",
"Atari 7800",
"Atari Lynx",
"Atari ST",
"MSX",
"PC Engine",
"TurboGrafx-16",
"ColecoVision",
"Intellivision",
"Commodore 64",
"Amiga",
"ZX Spectrum",
"Arcade (MAME)",
]
lines.extend([
", ".join(well_known) + f", and {len(system_ids) - len(well_known)}+ more.",
"",
f"Full list with per-file details: **[{SITE_URL}]({SITE_URL})**",
"",
"## Coverage",
"",
"| Platform | Coverage | Verified | Untested | Missing |",
"|----------|----------|----------|----------|---------|",
])
lines.extend(
[
", ".join(well_known) + f", and {len(system_ids) - len(well_known)}+ more.",
"",
f"Full list with per-file details: **[{SITE_URL}]({SITE_URL})**",
"",
"## Coverage",
"",
"| Platform | Coverage | Verified | Untested | Missing |",
"|----------|----------|----------|----------|---------|",
]
)
for name, cov in sorted(coverages.items(), key=lambda x: x[1]["platform"]):
pct = f"{cov['percentage']:.1f}%"
@@ -220,62 +278,66 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
f"{cov['verified']} | {cov['untested']} | {cov['missing']} |"
)
lines.extend([
"",
"## Build your own pack",
"",
"Clone the repo and generate packs for any platform, emulator, or system:",
"",
"```bash",
"# Full platform pack",
"python scripts/generate_pack.py --platform retroarch --output-dir dist/",
"python scripts/generate_pack.py --platform batocera --output-dir dist/",
"",
"# Single emulator or system",
"python scripts/generate_pack.py --emulator dolphin",
"python scripts/generate_pack.py --system sony-playstation-2",
"",
"# List available emulators and systems",
"python scripts/generate_pack.py --list-emulators",
"python scripts/generate_pack.py --list-systems",
"",
"# Verify your BIOS collection",
"python scripts/verify.py --all",
"python scripts/verify.py --platform batocera",
"python scripts/verify.py --emulator flycast",
"python scripts/verify.py --platform retroarch --verbose # emulator ground truth",
"```",
"",
f"Only dependency: Python 3 + `pyyaml`.",
"",
"## Documentation site",
"",
f"The [documentation site]({SITE_URL}) provides:",
"",
f"- **Per-platform pages** with file-by-file verification status and hashes",
f"- **Per-emulator profiles** with source code references for every file",
f"- **Per-system pages** showing which emulators and platforms cover each console",
f"- **Gap analysis** identifying missing files and undeclared core requirements",
f"- **Cross-reference** mapping files across {len(coverages)} platforms and {emulator_count} emulators",
"",
"## How it works",
"",
"Documentation and metadata can drift from what emulators actually load.",
"To keep packs accurate, each file is checked against the emulator's source code.",
"",
"1. **Read emulator source code** - trace every file the code loads, its expected hash and size",
"2. **Cross-reference with platforms** - match against what each platform declares",
"3. **Build packs** - include baseline files plus what each platform's cores need",
"4. **Verify** - run platform-native checks and emulator-level validation",
"",
])
lines.extend(
[
"",
"## Build your own pack",
"",
"Clone the repo and generate packs for any platform, emulator, or system:",
"",
"```bash",
"# Full platform pack",
"python scripts/generate_pack.py --platform retroarch --output-dir dist/",
"python scripts/generate_pack.py --platform batocera --output-dir dist/",
"",
"# Single emulator or system",
"python scripts/generate_pack.py --emulator dolphin",
"python scripts/generate_pack.py --system sony-playstation-2",
"",
"# List available emulators and systems",
"python scripts/generate_pack.py --list-emulators",
"python scripts/generate_pack.py --list-systems",
"",
"# Verify your BIOS collection",
"python scripts/verify.py --all",
"python scripts/verify.py --platform batocera",
"python scripts/verify.py --emulator flycast",
"python scripts/verify.py --platform retroarch --verbose # emulator ground truth",
"```",
"",
"Only dependency: Python 3 + `pyyaml`.",
"",
"## Documentation site",
"",
f"The [documentation site]({SITE_URL}) provides:",
"",
"- **Per-platform pages** with file-by-file verification status and hashes",
"- **Per-emulator profiles** with source code references for every file",
"- **Per-system pages** showing which emulators and platforms cover each console",
"- **Gap analysis** identifying missing files and undeclared core requirements",
f"- **Cross-reference** mapping files across {len(coverages)} platforms and {emulator_count} emulators",
"",
"## How it works",
"",
"Documentation and metadata can drift from what emulators actually load.",
"To keep packs accurate, each file is checked against the emulator's source code.",
"",
"1. **Read emulator source code** - trace every file the code loads, its expected hash and size",
"2. **Cross-reference with platforms** - match against what each platform declares",
"3. **Build packs** - include baseline files plus what each platform's cores need",
"4. **Verify** - run platform-native checks and emulator-level validation",
"",
]
)
contributors = fetch_contributors()
if contributors:
lines.extend([
"## Contributors",
"",
])
lines.extend(
[
"## Contributors",
"",
]
)
for c in contributors:
login = c["login"]
avatar = c.get("avatar_url", "")
@@ -285,18 +347,20 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
)
lines.append("")
lines.extend([
"",
"## Contributing",
"",
"See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.",
"",
"## License",
"",
"This repository provides BIOS files for personal backup and archival purposes.",
"",
f"*Auto-generated on {ts}*",
])
lines.extend(
[
"",
"## Contributing",
"",
"See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.",
"",
"## License",
"",
"This repository provides BIOS files for personal backup and archival purposes.",
"",
f"*Auto-generated on {ts}*",
]
)
return "\n".join(lines) + "\n"
@@ -332,7 +396,11 @@ def main():
print(f"{status} ./README.md")
contributing = generate_contributing()
status = "Generated" if write_if_changed("CONTRIBUTING.md", contributing) else "Unchanged"
status = (
"Generated"
if write_if_changed("CONTRIBUTING.md", contributing)
else "Unchanged"
)
print(f"{status} ./CONTRIBUTING.md")