fix: keep only aliases the emulator opens

Aliases equal to a name a platform launcher chooses were read in each emulator's code at its pin. Removed where the code opens no such name: xemu Complex_4627v1.03.bin (the core offers Complex_4627_v1.03.bin), mednafen gecard.pce, dosbox bios.rom, raze Roland_SC-55.sf2, nine DraStic names, and clk's upper-case MSX names, whose paths now read msx.rom, msx2.rom and msx2ext.rom as ROMCatalogue.cpp:777-841 names them. Kept aliases now name the code list they come from in the entry note.
This commit is contained in:
Abdessamad Derraz committed 2026-10-21 10:50:08 +02:00
1 parent a4310a1dee
commit 3ca746478d
17 files changed
+186 -46

No files matched your search

+2 -2
View File
@@ -129,7 +129,7 @@ files:
required: false
size: 524288
aliases: [amiga-os-310-cd32.rom, kick40060.CD32]
note: "CD32 Kickstart v3.1 rev 40.60"
note: "CD32 Kickstart v3.1 rev 40.60. candidates_cd32 tries cd32.rom, amiga-os-310-cd32.rom, kick40060.CD32, kick31.rom, then kick.rom."
source_ref: "source libretro/libretro.cpp:1811 (candidates_cd32)"
- name: cd32ext.rom
@@ -146,7 +146,7 @@ files:
system: commodore-cdtv
required: false
aliases: [kick34005.CDTV]
note: "CDTV extended ROM v1.00, used as kickstart candidate"
note: "CDTV extended ROM v1.00, used as kickstart candidate. candidates_cdtv tries cdtv.rom, kick34005.CDTV, kick13.rom, then kick.rom."
source_ref: "source libretro/libretro.cpp:1812 (candidates_cdtv)"
- name: cdtvext.rom
-1
View File
@@ -55,5 +55,4 @@ files:
description: "Games Express CD Card"
required: false
source_ref: "libretro.cpp:1057-1058, mednafen/settings.cpp:41, mednafen/pce/pce.cpp:374-411"
aliases: ["gecard.pce"]
note: "pce_cdbios = 'Games Express' or auto-detected via DetectGECD()."
+2 -2
View File
@@ -110,7 +110,7 @@ files:
mode: libretro
source_ref: "libretro.c:523-529"
aliases: ["PSXONPSP660.bin"]
note: "override_bios=1. Falls back to region BIOS if not found."
note: "override_bios=1. Tried as psxonpsp660.bin, PSXONPSP660.bin, then PSXONPSP660.BIN. Falls back to region BIOS if not found."
- name: "ps1_rom.bin"
description: "PS3 embedded PS1 BIOS, first 512KB extracted (region-free override)"
@@ -121,7 +121,7 @@ files:
mode: libretro
source_ref: "libretro.c:531-537"
aliases: ["PS1_ROM.bin"]
note: "override_bios=2. Falls back to region BIOS if not found."
note: "override_bios=2. Tried as ps1_rom.bin, PS1_ROM.bin, then PS1_ROM.BIN. Falls back to region BIOS if not found."
- name: "openbios.bin"
description: "OpenBIOS (open-source PS1 HLE BIOS, region-free override)"
+3 -6
View File
@@ -730,8 +730,7 @@ files:
# MSX (machine_name: "MSX")
# -------------------------------------------------------
- name: msx.rom
aliases: [MSX.ROM]
path: MSX/MSX.ROM
path: MSX/msx.rom
system: microsoft-msx
description: "Generic MSX BIOS"
size: 32768
@@ -778,8 +777,7 @@ files:
source_ref: "Machines/Utility/ROMCatalogue.cpp:809-816"
- name: msx2.rom
aliases: [MSX2.ROM]
path: MSX/MSX2.ROM
path: MSX/msx2.rom
system: microsoft-msx2
description: "Generic MSX2 BIOS"
size: 32768
@@ -789,8 +787,7 @@ files:
source_ref: "Machines/Utility/ROMCatalogue.cpp:818-825"
- name: msx2ext.rom
aliases: [MSX2EXT.ROM]
path: MSX/MSX2EXT.ROM
path: MSX/msx2ext.rom
system: microsoft-msx2
description: "MSX2 extension ROM"
size: 16384
-1
View File
@@ -637,7 +637,6 @@ files:
description: "IBM PCjr system ROM"
sha1: "1f5f7013f18c08ff50d7942e76c4fbd782412414"
required: false
aliases: ["bios.rom"]
min_size: 57344
validation: [size]
note: >
-1
View File
@@ -535,7 +535,6 @@ files:
sha1: "1f5f7013f18c08ff50d7942e76c4fbd782412414"
required: false
system: ibm-pcjr
aliases: ["bios.rom"]
min_size: 57344
validation: [size]
note: >
-3
View File
@@ -131,7 +131,6 @@ notes: |
files:
- name: nds_bios_arm9.bin
aliases: [NDS_Bios9.bin, bios9.bin, biosnds9.rom]
path: system/nds_bios_arm9.bin
system: nintendo-ds
required: false
@@ -154,7 +153,6 @@ files:
source_ref: "drastic r2.5.2.2 initialize_memory 0x1c4b0-0x1c4d4, libdrastic_arm64.so 0x2b6f0-0x2b708, DraSticActivity.smali:4084-4090, drastic_bios_readme.txt:1-31"
- name: nds_bios_arm7.bin
aliases: [NDS_Bios7.bin, bios7.bin, biosnds7.rom]
path: system/nds_bios_arm7.bin
system: nintendo-ds
required: false
@@ -177,7 +175,6 @@ files:
source_ref: "drastic r2.5.2.2 initialize_memory 0x1c508-0x1c52c, libdrastic_arm64.so 0x2b740-0x2b758, DraSticActivity.smali:4078-4083"
- name: nds_firmware.bin
aliases: [NDS_Lite_Firmware.bin, dsfirmware.bin, firmware.bin]
path: system/nds_firmware.bin
system: nintendo-ds
required: false
+1 -1
View File
@@ -36,7 +36,7 @@ files:
required: true
description: "Apple IIGS system ROM"
source_ref: "gsplus/src/config.c:136, gsplus/src/config.c:477-480, gsplus/src/config.c:1260-1317"
note: "Accepted sizes: 32768 (Apple //e), 131072 (ROM 01), 262144 (ROM 03)"
note: "g_kegs_rom_names tries the configured ROM path, then ROM, ROM.01, ROM.03, APPLE2GS.ROM, APPLE2GS.ROM2, xgs.rom, XGS.ROM, Rom03gd and 342-0077-b. Accepted sizes: 32768 (Apple //e), 131072 (ROM 01), 262144 (ROM 03)"
size: [32768, 131072, 262144]
validation: [size]
-1
View File
@@ -44,7 +44,6 @@ files:
- name: "gexpress.pce"
description: "Games Express CD Card"
required: false
aliases: ["gecard.pce"]
source_ref: "libretro.cpp:1057-1058, mednafen/settings.cpp:41, mednafen/pce/pce.cpp:373-411"
note: "pce_cdbios = 'Games Express' or auto-detected via DetectGECD()."
-1
View File
@@ -42,7 +42,6 @@ files:
- name: "gexpress.pce"
description: "Games Express CD Card"
required: false
aliases: ["gecard.pce"]
source_ref: "libretro.c:1906-1907"
note: "pce_fast_cdbios = 'Games Express'. For unlicensed Games Express titles."
+2 -1
View File
@@ -152,7 +152,8 @@ files:
required: true
description: "Kanji font ROM (shared by FS-A1WSX and FS-A1GT machines)"
validation: [sha1]
source_ref: "share/machines/Boosted_MSX2+_JP.xml:28, share/machines/Boosted_MSXturboR_with_IDE.xml:216"
source_ref: "share/machines/Boosted_MSX2+_JP.xml:27-28, share/machines/Panasonic_FS-A1WSX.xml:29-30, share/machines/Boosted_MSXturboR_with_IDE.xml:215-216, share/machines/Panasonic_FS-A1GT.xml:141-142"
note: "Panasonic_FS-A1WSX.xml and Boosted_MSX2+_JP.xml name it fs-a1wsx_kanjifont.rom, Panasonic_FS-A1GT.xml and Boosted_MSXturboR_with_IDE.xml name it fs-a1gt_kanjifont.rom, all four with the same sha1."
# -------------------------------------------------------
# Boosted_MSXturboR_with_IDE (msxturbor)
-1
View File
@@ -66,7 +66,6 @@ files:
note: "I_FatalError(\"Cannot find raze.pk3\") if absent. Built from the tree at each release. The hash is the copy in the 1.11.0b Windows zip."
- name: "raze.sf2"
aliases: ["Roland_SC-55.sf2"]
category: game_data
path: "soundfonts/raze.sf2"
required: false
+1 -1
View File
@@ -61,4 +61,4 @@ files:
validation: [size]
description: "Dreamcast flash memory"
source_ref: "core/hw/holly/sb_mem.cpp:22-23, 37-48, 58-64, core/types.h:212, 217"
note: "Written back as dc_nvmem.bin on exit. Missing, LoadRomFiles() fails even with a boot ROM present and the HLE BIOS runs."
note: "Tried as dc_nvmem.bin, dc_flash_wb.bin, dc_flash.bin, then dc_flash.bin.bin. Written back as dc_nvmem.bin on exit. Missing, LoadRomFiles() fails even with a boot ROM present and the HLE BIOS runs."
+1 -7
View File
@@ -82,7 +82,7 @@ files:
- name: Complex_4627.bin
path: Complex_4627.bin
aliases: [Complex.bin, Complex_4627v1.03.bin, cerbios.bin]
aliases: [Complex.bin, cerbios.bin]
required: true
size: [262144, 524288, 1048576]
validation: [size]
@@ -98,12 +98,6 @@ files:
Complex_4627_v1.03.bin, complex_4627.bin, cerbios.bin, Cerbios.bin,
bios.bin, xbox_bios.bin and Complex.bin offered as alternatives. The
core refuses to load when the chosen file is absent.
RetroDECK writes the BIOS folder's Complex.bin into flashrom_path of
the xemu.toml it prepares. ROCKNIX ships an xemu.toml whose
flashrom_path is bios/xemu/bios/Complex_4627v1.03.bin. Batocera writes
bios/cerbios.bin into flashrom_path for its chihiro system and
bios/Complex_4627.bin for xbox. EmuDeck writes
bios/Complex_4627v1.03.bin into flashrom_path.
source_ref:
standalone: "system/vl.c:3041-3053, hw/xbox/xbox.c:63-123"
libretro: "ui/xemu-libretro.c:115-118, ui/xemu-libretro.c:195-196, ui/xemu-libretro.c:210-236"
+20 -16
View File
@@ -47,7 +47,7 @@ files:
validation: [crc32]
aliases: [dragon32, d32rom, "Dragon Data Ltd - Dragon 32 - IC17"]
source_ref: "src/xroar.c:649 (romlist d32), src/dragon/dragon32.c:40 (default @dragon32), src/dragon/dragon32.c:107,110-116,131-132 (load + CRC)"
note: "Combined 16K ROM. Loaded into a single 16384-byte rombank slot."
note: "Combined 16K ROM. Loaded into a single 16384-byte rombank slot. Romlist d32 tries d32, dragon32, d32rom, Dragon Data Ltd - Dragon 32 - IC17."
# ---- Dragon 64 ----
@@ -60,7 +60,7 @@ files:
validation: [crc32]
aliases: [d64rom1, d64rom1.rom, dragrom, "Dragon Data Ltd - Dragon 64 - IC17", "Dragon Data Ltd - TANO IC18", "Eurohard S.A. - Dragon 200 IC18"]
source_ref: "src/xroar.c:647 (romlist d64_1), src/xroar.c:653 (romlist dragon64), src/dragon/dragon64.c:151-157,169-171 (load + CRC)"
note: "IC17 ROM. Required for the machine to start."
note: "IC17 ROM. Required for the machine to start. Romlist d64_1 tries d64_1, d64rom1, Dragon Data Ltd - Dragon 64 - IC17, Dragon Data Ltd - TANO IC18, Eurohard S.A. - Dragon 200 IC18, dragrom."
- name: "d64_2.rom"
system: dragon64
@@ -71,7 +71,7 @@ files:
validation: [crc32]
aliases: [d64rom2, "Dragon Data Ltd - Dragon 64 - IC18", "Dragon Data Ltd - TANO IC17", "Eurohard S.A. - Dragon 200 IC17"]
source_ref: "src/xroar.c:648 (romlist d64_2), src/xroar.c:654 (romlist dragon64_alt), src/dragon/dragon64.c:160-166,174-176 (load + CRC)"
note: "IC18 ROM. 64K mode alternate BASIC. Machine starts without it (32K mode only)."
note: "IC18 ROM. 64K mode alternate BASIC. Machine starts without it (32K mode only). Romlist d64_2 tries d64_2, d64rom2, Dragon Data Ltd - Dragon 64 - IC18, Dragon Data Ltd - TANO IC17, Eurohard S.A. - Dragon 200 IC17."
# ---- Dragon 200-E ----
@@ -85,7 +85,7 @@ files:
validation: [crc32]
aliases: [d200e_rom1, ic18_v1.4e.ic34]
source_ref: "src/xroar.c:650 (romlist d200e_1), src/xroar.c:656 (romlist dragon200e), src/xroar.c:741 (crclist)"
note: "Required for Dragon 200-E. Falls back to d64_1 then generic dragon if not found."
note: "Required for Dragon 200-E. Falls back to d64_1 then generic dragon if not found. Romlist d200e_1 tries d200e_1, d200e_rom1, ic18_v1.4e.ic34."
- name: "d200e_2.rom"
system: dragon64
@@ -96,7 +96,7 @@ files:
crc32: "48b985df"
aliases: [d200e_rom2, ic17_v1.4e.ic37]
source_ref: "src/xroar.c:651 (romlist d200e_2), src/xroar.c:657 (romlist dragon200e_alt), src/rom.c:91 (0x48b985df = Dragon 200-E 64K BASIC)"
note: "64K mode alternate. Falls back to d64_2 if not found."
note: "64K mode alternate. Falls back to d64_2 if not found. Romlist d200e_2 tries d200e_2, d200e_rom2, ic17_v1.4e.ic37."
- name: "d200e_26.rom"
system: dragon64
@@ -107,7 +107,7 @@ files:
crc32: "565724bc"
aliases: [rom26.ic1]
source_ref: "src/xroar.c:658 (romlist dragon200e_charset), src/dragon/dragon.c:430-447 (ext_charset load), src/rom.c:92 (0x565724bc = Dragon 200-E Character Set)"
note: "Spanish character set. Loaded into a 4096-byte rombank. Machine works without it (uses standard charset)."
note: "Spanish character set. Loaded into a 4096-byte rombank. Machine works without it (uses standard charset). Romlist dragon200e_charset tries d200e_26, rom26.ic1."
# ---- Dragon Professional (Alpha) ----
@@ -124,6 +124,7 @@ files:
Required for Dragon Professional machine. Loaded as extbas_rom into the
BOOT bank. rombank_verify_crc accepts any member of @dragonpro_boot,
which also holds 0xd6172b56 for the v0.4 slot.
Romlist dragonpro_boot tries alpha-boot-v1.0, alpha_bt_10, Dragon Data Ltd - Dragon Alpha Boot v1.0 150584, alpha-boot-v0.4, alpha_bt_04.
- name: "alpha-boot-v0.4.rom"
system: dragon64
@@ -139,6 +140,7 @@ files:
v1.0 image is found. The dragonpro_boot crclist carries 0xd6172b56 next
to the v1.0 value, and the ROM metadata table names it Dragon
Professional Boot 0.4.
Romlist dragonpro_boot tries alpha-boot-v1.0, alpha_bt_10, Dragon Data Ltd - Dragon Alpha Boot v1.0 150584, alpha-boot-v0.4, alpha_bt_04.
- name: "alpha-basic.rom"
system: dragon64
@@ -149,7 +151,7 @@ files:
validation: [crc32]
aliases: [alpha_ba, "Dragon Data Ltd - Dragon Alpga Basic"]
source_ref: "src/xroar.c:661 (romlist dragonpro_basic), src/xroar.c:748 (crclist = @d64_1), src/dragon/dragonpro.c:247 (ROM0 bank 16384), src/dragon/dragonpro.c:260-263 (load), src/dragon/dragonpro.c:274 (0x84f68bf9 = Dragon 64 32K mode BASIC)"
note: "Loaded as altbas_rom into the 32K BASIC bank. Falls back to d64_1 if not found."
note: "Loaded as altbas_rom into the 32K BASIC bank. Falls back to d64_1 if not found. Romlist dragonpro_basic tries alpha-basic, alpha_ba, Dragon Data Ltd - Dragon Alpga Basic, @d64_1."
# ---- Tandy CoCo (Colour BASIC) ----
@@ -172,7 +174,7 @@ files:
validation: [crc32]
aliases: ["Color Basic v1.2 (1982)(Tandy)"]
source_ref: "src/xroar.c:663 (romlist coco), src/xroar.c:752 (crclist bas12)"
note: "Alternative to bas13. Second in fallback order."
note: "Alternative to bas13. Second in fallback order. Romlist coco tries bas13, bas12, Color Basic v1.2 (1982)(Tandy), bas11, bas10. Romlist coco2 tries bas12, @coco."
- name: "bas11.rom"
system: coco
@@ -271,7 +273,7 @@ files:
validation: [crc32]
aliases: [adv070_u24]
source_ref: "src/xroar.c:679 (romlist deluxecoco), src/xroar.c:763 (crclist), src/dragon/deluxecoco.c:213-216 (load)"
note: "Primary ROM for the Deluxe CoCo prototype. Loaded as extbas_rom."
note: "Primary ROM for the Deluxe CoCo prototype. Loaded as extbas_rom. Romlist deluxecoco tries adv070_u24, deluxe."
- name: "adv071_u24.rom"
system: coco
@@ -291,6 +293,7 @@ files:
required: false
aliases: [adv073_u24]
source_ref: "src/xroar.c:683 (romlist deluxecoco3), src/dragon/deluxecoco.c:237-240 (load)"
note: "Romlist deluxecoco3 tries adv073-2_u24, adv073_u24."
# ---- Dynacom MX-1600 (Brazilian clone) ----
@@ -302,7 +305,7 @@ files:
validation: [crc32]
aliases: [mx1600bas_zephyr]
source_ref: "src/xroar.c:685 (romlist mx1600), src/xroar.c:754 (crclist mx1600)"
note: "Required for MX-1600. Zephyr-patched variant (CRC32 d11b1c96) is an alias."
note: "Required for MX-1600. Zephyr-patched variant (CRC32 d11b1c96) is an alias. Romlist mx1600 tries mx1600bas, mx1600bas_zephyr."
- name: "mx1600extbas.rom"
system: coco
@@ -381,7 +384,7 @@ files:
crc32: "b44536f6"
aliases: ["Dragon Data Ltd - DragonDOS 1.0"]
source_ref: "src/xroar.c:708 (romlist dragondos), src/xroar.c:712 (romlist dragondos_compat), src/dragondos.c:173 (default @dragondos_compat), src/rom.c:131 (0xb44536f6 = DragonDOS 1.0)"
note: "Fifth name in the dragondos romlist, which @dragondos_compat tries after the dosplus and superdos lists."
note: "Fifth name in the dragondos romlist, which @dragondos_compat tries after the dosplus and superdos lists. Romlist dragondos tries ddos12a, ddos12, ddos40, ddos15, ddos10, Dragon Data Ltd - DragonDOS 1.0."
- name: "dplus49b.rom"
system: dragon64
@@ -400,7 +403,7 @@ files:
crc32: "d4d954a0"
aliases: [dosplus-4.8, DOSPLUS]
source_ref: "src/xroar.c:709 (romlist dosplus), src/xroar.c:712 (romlist dragondos_compat), src/dragondos.c:173 (default @dragondos_compat), src/rom.c:137 (0xd4d954a0 = DOSplus 4.8)"
note: "Second name in the dosplus romlist, the first list @dragondos_compat tries."
note: "Second name in the dosplus romlist, the first list @dragondos_compat tries. Romlist dosplus tries dplus49b, dplus48, dosplus-4.8, DOSPLUS."
- name: "sdose6.rom"
system: dragon64
@@ -410,7 +413,7 @@ files:
crc32: "8c1d6c45"
aliases: ["PNP - SuperDOS E6"]
source_ref: "src/xroar.c:710 (romlist superdos), src/rom.c:141 (0x8c1d6c45 = SuperDOS E6)"
note: "Latest SuperDOS. Older versions: sdose5, sdose4."
note: "Latest SuperDOS. Older versions: sdose5, sdose4. Romlist superdos tries sdose6, PNP - SuperDOS E6, sdose5, sdose4."
- name: "cdos20.rom"
system: dragon64
@@ -418,6 +421,7 @@ files:
required: false
aliases: [CDOS20, "CumanaDOSv2.0"]
source_ref: "src/xroar.c:711 (romlist cumana)"
note: "Romlist cumana tries cdos20, CDOS20, CumanaDOSv2.0."
- name: "delta2.rom"
system: dragon64
@@ -427,7 +431,7 @@ files:
crc32: "307fb37c"
aliases: ["Premier Micros - DeltaDOS"]
source_ref: "src/xroar.c:717 (romlist delta), src/deltados.c:160 (default @delta), src/rom.c:146 (0x307fb37c = Delta System 2.0)"
note: "Latest Delta version. Older versions: delta1a, delta19, delta, deltados."
note: "Latest Delta version. Older versions: delta1a, delta19, delta, deltados. Romlist delta tries delta2, delta1a, delta19, delta, deltados, Premier Micros - DeltaDOS."
- name: "cp450dsk.rom"
system: coco
@@ -453,7 +457,7 @@ files:
required: false
aliases: [MCX_Basic_21]
source_ref: "src/xroar.c:730 (romlist mcx128), src/mcx128.c:208 (default @mcx128)"
note: "128K memory expansion for MC-10. Adds enhanced BASIC."
note: "128K memory expansion for MC-10. Adds enhanced BASIC. Romlist mcx128 tries mcx128, MCX_Basic_21."
- name: "mcx128a.rom"
system: mc10
@@ -461,7 +465,7 @@ files:
required: false
aliases: [MCX_Basic_21_AZERTY]
source_ref: "src/xroar.c:731 (romlist mcx128_azerty), src/xroar.c:638-639 (cart mcx128a)"
note: "AZERTY keyboard variant for Alice. Same MCX128 hardware."
note: "AZERTY keyboard variant for Alice. Same MCX128 hardware. Romlist mcx128_azerty tries mcx128a, MCX_Basic_21_AZERTY."
- name: "yados.rom"
system: coco
+153
View File
@@ -0,0 +1,153 @@
"""A profile alias is a name the emulator's own code opens.
Platform launchers pick names of their own: Batocera passes cerbios.bin to
xemu, ROCKNIX and EmuDeck write Complex_4627v1.03.bin into xemu.toml. Those
names live in the platform's ``launchers:`` layer. Copied into a profile as
aliases, they claimed that xemu opens them, and xemu-libretro offers
Complex_4627_v1.03.bin, not Complex_4627v1.03.bin (ui/xemu-libretro.c:115-118).
Two checks read the committed data:
- an alias equal to a name a launcher of the same emulator chooses is kept
only when the entry's own note or description names it in a sentence that
speaks of no platform, next to a ``source_ref`` into the emulator's code;
- no entry cites a platform's launcher script as its source.
"""
from __future__ import annotations
import re
import unittest
from collections import defaultdict
from pathlib import Path
import yaml
REPO_ROOT = Path(__file__).resolve().parent.parent
PLATFORMS = REPO_ROOT / "platforms"
EMULATORS = REPO_ROOT / "emulators"
# Words that name a platform in prose. MiSTer's registry key carries its
# hardware suffix, the prose says MiSTer.
PLATFORM_WORDS = (
"retroarch", "batocera", "recalbox", "retrobat", "emudeck", "lakka",
"retrodeck", "romm", "rocknix", "retropie", "bizhawk", "mister",
)
# Launcher sources: configgen and emulatorLauncher generators, EmuDeck and
# RetroPie scripts, a ref annotated as a launcher.
LAUNCHER_REF = re.compile(
r"Generator\.(?:py|cs)\b|\bconfiggen\b|\bemulatorLauncher\b|"
r"\bemuDeck\w*\.sh\b|\bscriptmodules/|\(launcher\)",
)
# Profiles whose entries still rest on a launcher, with the fact that blocks
# reading the emulator itself.
LAUNCHER_SOURCED = {
"lexaloffle": "PICO-8 and Voxatron are sold binaries, and no copy of either is held to read",
}
_SENTENCE = re.compile(r"(?<=[.!?])\s+(?=[A-Z0-9(\"'])")
def _profiles() -> dict[str, dict]:
return {
path.stem: yaml.safe_load(path.read_text(encoding="utf-8")) or {}
for path in sorted(EMULATORS.glob("*.yml"))
}
def _launcher_names() -> dict[str, set[tuple[str, str]]]:
"""Folded file name -> (platform, emulator) of each launcher choosing it."""
names: dict[str, set[tuple[str, str]]] = defaultdict(set)
for path in sorted(PLATFORMS.glob("*.yml")):
config = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
for record in config.get("launchers") or []:
for name in record.get("names") or []:
base = str(name).rsplit("/", 1)[-1].casefold()
names[base].add((path.stem, str(record.get("emulator", ""))))
return names
def _text(value: object) -> str:
if isinstance(value, dict):
return " ".join(_text(v) for v in value.values())
if isinstance(value, list):
return " ".join(_text(v) for v in value)
return str(value or "")
def _named_without_platform(alias: str, prose: str) -> bool:
for sentence in _SENTENCE.split(" ".join(prose.split())):
if alias not in sentence:
continue
folded = sentence.casefold()
if not any(re.search(rf"\b{word}", folded) for word in PLATFORM_WORDS):
return True
return False
class ProfileAliasesAreCodeNames(unittest.TestCase):
def test_alias_a_launcher_chooses_is_named_by_the_code(self) -> None:
launchers = _launcher_names()
offenders = []
for key, profile in _profiles().items():
emulator_names = {key} | {str(c) for c in profile.get("cores") or []}
for entry in profile.get("files") or []:
prose = _text(entry.get("note")) + " " + _text(entry.get("description"))
for alias in entry.get("aliases") or []:
alias = str(alias)
chosen_by = {
platform
for platform, emulator in launchers.get(
alias.rsplit("/", 1)[-1].casefold(), ()
)
if emulator in emulator_names
}
if not chosen_by:
continue
if entry.get("source_ref") and _named_without_platform(alias, prose):
continue
offenders.append(
f"{key}: {entry.get('name')} alias {alias} "
f"(launchers: {', '.join(sorted(chosen_by))})"
)
self.assertEqual(
offenders, [],
"an alias a platform launcher chooses must be named by the emulator's "
"code, stated in the entry's note with its source_ref, or removed",
)
def test_check_catches_a_launcher_name(self) -> None:
self.assertFalse(_named_without_platform(
"cerbios.bin", "Batocera writes bios/cerbios.bin into flashrom_path.",
))
self.assertTrue(_named_without_platform(
"cerbios.bin", "The core option offers cerbios.bin. Batocera writes it.",
))
class EntriesCiteTheEmulator(unittest.TestCase):
def test_no_source_ref_is_a_launcher_script(self) -> None:
offenders = []
for key, profile in _profiles().items():
if key in LAUNCHER_SOURCED:
continue
for entry in profile.get("files") or []:
ref = _text(entry.get("source_ref"))
if LAUNCHER_REF.search(ref):
offenders.append(f"{key}: {entry.get('name')}: {ref}")
self.assertEqual(offenders, [])
def test_known_exceptions_still_need_it(self) -> None:
profiles = _profiles()
for key in LAUNCHER_SOURCED:
refs = [_text(e.get("source_ref")) for e in profiles[key].get("files") or []]
self.assertTrue(
any(LAUNCHER_REF.search(r) for r in refs),
f"{key} no longer cites a launcher: drop it from LAUNCHER_SOURCED",
)
if __name__ == "__main__":
unittest.main()
+1 -1
View File
@@ -39,7 +39,7 @@ Every module in `tests/`, by the area it guards.
|------|----------|---------|
| Core regression suites | synthetic | `test_e2e`, `test_audit_regressions`, `test_tool_messages` |
| File resolution and identity | synthetic + collection | `test_adler32_resolution`, `test_agnostic_scan`, `test_agnostic_scan_mode`, `test_agnostic_scope`, `test_agnostic_substitute`, `test_archive_choice`, `test_bios_companions`, `test_bundled_identity`, `test_casefold_cache`, `test_db_aliases`, `test_declared_names`, `test_derivations`, `test_directory_entries`, `test_extra_identity`, `test_foreign_tree`, `test_foreign_tree_names`, `test_frontend_digest`, `test_game_data_homonyms`, `test_hashing`, `test_identity`, `test_md5_pack_context`, `test_name_tiebreak`, `test_nec_filing`, `test_owner_resolution`, `test_path_suffix`, `test_resolution_evidence`, `test_shipped_content`, `test_twin_declarations`, `test_validated_choice`, `test_variant_choice`, `test_variant_identity`, `test_zipped_member` |
| Verification, cross-reference and profile checks | synthetic + profiles | `test_crypto_aes`, `test_crypto_unique_data`, `test_crypto_verify`, `test_case_insensitive_platforms`, `test_checks_have_values`, `test_core_file_fills_declaration`, `test_cross_reference_sources`, `test_file_consumers`, `test_fileless_audit`, `test_gap_settlement`, `test_hidden_extras`, `test_launcher_layer`, `test_native_mode`, `test_no_case_collisions`, `test_path_conflict_status`, `test_path_null_copies`, `test_profile_checks`, `test_romm_hash_rule`, `test_shared_groups`, `test_standalone_mode`, `test_undeclared_dedup`, `test_unplaced_extras`, `test_validation_scope`, `test_verify_all_dir`, `test_verify_emulator_evidence`, `test_verify_listing`, `test_verify_pack_choice` |
| Verification, cross-reference and profile checks | synthetic + profiles | `test_crypto_aes`, `test_crypto_unique_data`, `test_crypto_verify`, `test_case_insensitive_platforms`, `test_checks_have_values`, `test_core_file_fills_declaration`, `test_cross_reference_sources`, `test_file_consumers`, `test_fileless_audit`, `test_gap_settlement`, `test_hidden_extras`, `test_launcher_aliases`, `test_launcher_layer`, `test_native_mode`, `test_no_case_collisions`, `test_path_conflict_status`, `test_path_null_copies`, `test_profile_checks`, `test_romm_hash_rule`, `test_shared_groups`, `test_standalone_mode`, `test_undeclared_dedup`, `test_unplaced_extras`, `test_validation_scope`, `test_verify_all_dir`, `test_verify_emulator_evidence`, `test_verify_listing`, `test_verify_pack_choice` |
| Packs and manifests | synthetic + real packs | `test_artifact_lock`, `test_atomic_artifacts`, `test_batocera_cores`, `test_deterministic_zip`, `test_emulator_pack_counts`, `test_finalize_pack_names`, `test_large_file_cache`, `test_libretro_layout`, `test_manifest_entry`, `test_pack_conformance_dirs`, `test_pack_core_extras`, `test_pack_counts`, `test_pack_destinations`, `test_pack_failures`, `test_pack_file_names`, `test_pack_grouping`, `test_pack_integrity`, `test_pack_member_identity`, `test_pack_readme`, `test_platform_inheritance`, `test_platform_keys`, `test_required_only_archives`, `test_required_only_twins`, `test_split_extras`, `test_split_names`, `test_split_pack`, `test_system_pack_extras`, `test_system_pack_parity`, `test_torrentzip`, `test_which_pack` |
| Slots and regions | synthetic + profiles | `test_region`, `test_region_agnostic_scan`, `test_region_groups`, `test_region_held`, `test_region_platform_index`, `test_region_required_only`, `test_slot`, `test_slots`, `test_slots_shipped_file` |
| Hardware targets and systems | synthetic + target files | `test_extract_targets`, `test_lakka_targets`, `test_libretro_slugs`, `test_system_ids`, `test_system_selection`, `test_target_names`, `test_target_scrapers`, `test_target_systems`, `test_target_verify` |