mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-11 12:33:53 -06:00
feat: write config_reads into the profiles
Where each shipped build finds the config a platform installs and reads every key it opens a file from, read at the build the platform ships: duckstation (EmuELEC, ROCKNIX, RetroBat), xemu, armsx2, hatari, melonDS, dsperate, NanoBoyAdvance, mednafen (ROCKNIX's sydarn fork) and ares, gzdoom, xroar, lrps2 and the amiberry builds at their pins. pin_build names the builds ROCKNIX, EmuELEC and AmberELEC compile, revision the ones RetroBat and Flathub install unpinned. tests/test_launcher_evidence.py covers the rule, the extractor helpers, the invariants and the chains that move placements.
This commit is contained in:
1 parent
f950482567
commit
a6716796a9
15 files changed
+743
No files matched your search
@@ -32,6 +32,13 @@ systems:
|
||||
standalone_directories:
|
||||
- "getcwd"
|
||||
- "rom_path = kickstarts"
|
||||
config_reads:
|
||||
- file: "*.uae"
|
||||
source_ref: "src/main.cpp:926-934"
|
||||
keys:
|
||||
- key: "kickstart_rom_file"
|
||||
source_ref: "src/cfgfile.cpp:6050, src/memory.cpp:1907-1916"
|
||||
|
||||
notes: |
|
||||
Amiberry 5.6.5 (src/osdep/target.h:27). Every folder it reads is below
|
||||
its start path: $EXTERNAL_FILES_DIR or $XDG_DATA_HOME when either holds a
|
||||
|
||||
@@ -43,6 +43,15 @@ standalone_directories:
|
||||
- "AMIBERRY_HOME_DIR/roms"
|
||||
- "~/Amiberry/roms"
|
||||
- "whdboot_path = whdboot"
|
||||
config_reads:
|
||||
- file: "*.uae"
|
||||
source_ref: "src/main.cpp:986-994"
|
||||
keys:
|
||||
- key: "kickstart_rom_file"
|
||||
source_ref: "src/cfgfile.cpp:6122, src/memory.cpp:1974-1983"
|
||||
- key: "$(FILE_PATH)"
|
||||
source_ref: "src/cfgfile.cpp:389"
|
||||
|
||||
notes: |
|
||||
Amiberry 7.1.1 (CMakeLists.txt:3-4). The ROM path is rom_path in
|
||||
amiberry.conf, else roms/ below the home directory: $AMIBERRY_HOME_DIR,
|
||||
|
||||
@@ -56,6 +56,49 @@ systems:
|
||||
- zx-spectrum
|
||||
- zx-spectrum-128
|
||||
|
||||
config_reads:
|
||||
- file: "settings.bml"
|
||||
source_ref: "desktop-ui/desktop-ui.cpp:9-35, 100-103, 114, desktop-ui/settings/settings.cpp:31-42, 263-286, nall/nall/path.cpp:123-142"
|
||||
keys:
|
||||
- key: "ColecoVision/Firmware/BIOS.World"
|
||||
source_ref: "desktop-ui/emulator/colecovision.cpp:10-12, 42-50, mia/system/colecovision.cpp:7-9"
|
||||
- key: "MSX/Firmware/BIOS.Japan"
|
||||
source_ref: "desktop-ui/emulator/msx.cpp:16-19, 44-53"
|
||||
- key: "FamicomDiskSystem/Firmware/BIOS.Japan"
|
||||
source_ref: "desktop-ui/emulator/famicom-disk-system.cpp:17-19, 89-97"
|
||||
- key:
|
||||
- "Nintendo64DD/Firmware/BIOS.Japan"
|
||||
- "Nintendo64DD/Firmware/BIOS.US"
|
||||
- "Nintendo64DD/Firmware/BIOS.DEV"
|
||||
source_ref: "desktop-ui/emulator/nintendo-64dd.cpp:15-19, 59-73"
|
||||
condition: "the game's region"
|
||||
- key: "GameBoyAdvance/Firmware/BIOS.World"
|
||||
source_ref: "desktop-ui/emulator/game-boy-advance.cpp:12-14, 55-63"
|
||||
- key:
|
||||
- "MasterSystem/Firmware/BIOS.US"
|
||||
- "MasterSystem/Firmware/BIOS.Japan"
|
||||
- "MasterSystem/Firmware/BIOS.Europe"
|
||||
source_ref: "desktop-ui/emulator/master-system.cpp:12-16, 93-107"
|
||||
condition: "the game's region"
|
||||
- key: "GameGear/Firmware/BIOS.World"
|
||||
source_ref: "desktop-ui/emulator/game-gear.cpp:10-12, 30-40"
|
||||
- key:
|
||||
- "MegaCD/Firmware/BIOS.US"
|
||||
- "MegaCD/Firmware/BIOS.Japan"
|
||||
- "MegaCD/Firmware/BIOS.Europe"
|
||||
source_ref: "desktop-ui/emulator/mega-cd.cpp:15-19, 63-77"
|
||||
condition: "the disc's region"
|
||||
- key: "NeoGeoPocket/Firmware/BIOS.World"
|
||||
source_ref: "desktop-ui/emulator/neo-geo-pocket.cpp:10-12, 32-40"
|
||||
- key: "NeoGeoPocketColor/Firmware/BIOS.World"
|
||||
source_ref: "desktop-ui/emulator/neo-geo-pocket-color.cpp:10-12, 32-40"
|
||||
- key:
|
||||
- "PlayStation/Firmware/BIOS.US"
|
||||
- "PlayStation/Firmware/BIOS.Japan"
|
||||
- "PlayStation/Firmware/BIOS.Europe"
|
||||
source_ref: "desktop-ui/emulator/playstation.cpp:19-23, 87-101"
|
||||
condition: "the disc's region"
|
||||
|
||||
notes: |
|
||||
Multi-system emulator by Near (byuu), successor to higan/bsnes. Focuses on
|
||||
accuracy and preservation. 40 emulators registered at this pin
|
||||
|
||||
@@ -48,6 +48,25 @@ data_root:
|
||||
source_ref: "source pcsx2/Pcsx2Config.cpp:2523-2530, pcsx2/Pcsx2Config.cpp:2540-2560, pcsx2/Pcsx2Config.cpp:2567-2589"
|
||||
note: "portable.ini or portable.txt beside the binary makes its folder the root"
|
||||
|
||||
pin_build:
|
||||
- platform: rocknix
|
||||
repo: "https://github.com/ROCKNIX/distribution"
|
||||
revision: "20261101"
|
||||
path: "projects/ROCKNIX/packages/emulators/standalone/armsx2-sa/package.mk"
|
||||
variable: PKG_VERSION
|
||||
value: "19c83bf065ed21a19d8c46a1f578e37d2dab8efd"
|
||||
config_reads:
|
||||
- file: "PCSX2.ini"
|
||||
platforms: [rocknix]
|
||||
source_ref: "pcsx2-qt/QtHost.cpp:1307, 1325-1331, pcsx2/Pcsx2Config.cpp:2398-2491, pcsx2/VMManager.cpp:630-641"
|
||||
keys:
|
||||
- key: "[Folders] Bios"
|
||||
source_ref: "pcsx2/Pcsx2Config.cpp:2514-2524"
|
||||
condition: "[UI] SettingsVersion 1, else the ini is reset (pcsx2-qt/QtHost.cpp:1331-1342)"
|
||||
- key: "[Filenames] BIOS"
|
||||
source_ref: "pcsx2/Pcsx2Config.cpp:1879-1881, 2258-2264, pcsx2/ps2/BiosTools.cpp:258-282, 333-348, pcsx2/VMManager.cpp:1638"
|
||||
condition: "empty: the first PS2 BIOS of 4 to 8 MB found in [Folders] Bios"
|
||||
|
||||
notes: |
|
||||
PlayStation 2 emulator, a GPL-3.0 fork of PCSX2 that replaces the x86-64 only
|
||||
EE, IOP, VU and vtlb fast memory recompilers with native AArch64 ones. One tree
|
||||
|
||||
@@ -32,6 +32,32 @@ data_root:
|
||||
source_ref: "src/frontend/sdl/config.cpp:39-49"
|
||||
note: "~/.config/dsperate when XDG_CONFIG_HOME is unset. System files are read wherever the [paths] keys of the ini point."
|
||||
|
||||
config_reads:
|
||||
- file: "dsperate.ini"
|
||||
platforms: [rocknix]
|
||||
revision: "ddf2910e6d80220c6b22b4df61f0786ac9879cda"
|
||||
revision_from: "PKG_VERSION 3.0.5, the release binaries CI built from tag v3.0.5"
|
||||
source_ref: "src/frontend/sdl/main.cpp:1065, 1155-1157, src/frontend/sdl/config.cpp:64-81"
|
||||
keys:
|
||||
- key:
|
||||
- "[paths] bios9"
|
||||
- "[paths] bios7"
|
||||
source_ref: "src/frontend/sdl/main.cpp:1175, 1270-1274, src/core/nds.cpp:114-129"
|
||||
condition: "both present, otherwise FreeBIOS"
|
||||
- key: "[paths] firmware"
|
||||
source_ref: "src/frontend/sdl/main.cpp:1178, 1270, src/core/nds.cpp:123, 134-135"
|
||||
- key:
|
||||
- "[paths] bios9i"
|
||||
- "[paths] bios7i"
|
||||
source_ref: "src/frontend/sdl/main.cpp:1179-1186, 1319-1322, 1331-1334, src/core/nds_dsi.cpp:88-99"
|
||||
condition: "DSi session"
|
||||
- key: "[paths] dsi_firmware"
|
||||
source_ref: "src/frontend/sdl/main.cpp:1176-1178, 1270"
|
||||
condition: "DSi session"
|
||||
- key: "[paths] dsi_nand"
|
||||
source_ref: "src/frontend/sdl/main.cpp:1158-1162, 1324-1326, 1337, src/core/nds_dsi.cpp:114-120"
|
||||
condition: "--dsi-mode, BootMenuDSi.nds or a .dspr.nds shortcut"
|
||||
|
||||
notes: |
|
||||
Nintendo DS emulator for ARM handhelds with a DSi mode. ROCKNIX installs the
|
||||
release tarball for its architecture and runs it with --config pointing at
|
||||
|
||||
@@ -33,6 +33,61 @@ data_root:
|
||||
source_ref: "src/core/core.cpp:137-151, src/core/core.cpp:190-215"
|
||||
note: "portable.txt or settings.ini beside the executable, or beside the AppImage, makes that folder the root"
|
||||
|
||||
pin_build:
|
||||
- platform: emuelec
|
||||
repo: "https://github.com/EmuELEC/EmuELEC"
|
||||
revision: "v4.8"
|
||||
path: "packages/sx05re/emulators/duckstation/package.mk"
|
||||
variable: PKG_VERSION
|
||||
value: "fd3507c16d098fb32806c281caaefb205946da8a"
|
||||
- platform: rocknix
|
||||
repo: "https://github.com/ROCKNIX/distribution"
|
||||
revision: "20261101"
|
||||
path: "projects/ROCKNIX/packages/emulators/standalone/duckstation-sa/package.mk"
|
||||
variable: PKG_VERSION
|
||||
value: "0.1-10998"
|
||||
config_reads:
|
||||
- file: "settings.ini"
|
||||
platforms: [emuelec]
|
||||
source_ref: "src/frontend-common/common_host_interface.cpp:403-407, 3042-3050, 3304-3327, src/duckstation-nogui/main.cpp:62-64, 137-140, src/duckstation-nogui/nogui_host_interface.cpp:39-42"
|
||||
keys:
|
||||
- key: "[BIOS] SearchDirectory"
|
||||
source_ref: "src/core/host_interface.cpp:253-260"
|
||||
- key:
|
||||
- "[BIOS] PathNTSCU"
|
||||
- "[BIOS] PathNTSCJ"
|
||||
- "[BIOS] PathPAL"
|
||||
source_ref: "src/core/host_interface.cpp:262-375, src/core/system.cpp:817"
|
||||
condition: "the console region; an empty value scans SearchDirectory"
|
||||
- file: "settings.ini"
|
||||
platforms: [rocknix]
|
||||
revision: "9b0a4ec559ae83bfdb14685932b036ad7c1701be"
|
||||
revision_from: "PKG_VERSION 0.1-10998, the AppImage of tag v0.1-10998"
|
||||
source_ref: "src/core/core.cpp:105-223, 227-230, 232-275, src/duckstation-qt/qthost.cpp:796-800"
|
||||
keys:
|
||||
- key: "[BIOS] SearchDirectory"
|
||||
source_ref: "src/core/settings.cpp:2709-2719, 2723"
|
||||
- key:
|
||||
- "[BIOS] PathNTSCU"
|
||||
- "[BIOS] PathNTSCJ"
|
||||
- "[BIOS] PathPAL"
|
||||
source_ref: "src/core/bios.cpp:351-458, src/core/system.cpp:2923"
|
||||
condition: "the console region; an empty value scans SearchDirectory"
|
||||
- file: "settings.ini"
|
||||
platforms: [retrobat]
|
||||
revision: "5fd366809053fe287291de7a39752c4d5d5b146b"
|
||||
revision_from: "version 0.1-11752-g5fd366809 of duckstation.exe in RetroBat's stable duckstation.7z, 2026-11-10"
|
||||
source_ref: "src/core/core.cpp:131-249, 253-256, 258-301, src/duckstation-qt/qthost.cpp:803-807"
|
||||
keys:
|
||||
- key: "[BIOS] SearchDirectory"
|
||||
source_ref: "src/core/settings.cpp:2859-2869, 2873"
|
||||
- key:
|
||||
- "[BIOS] PathNTSCU"
|
||||
- "[BIOS] PathNTSCJ"
|
||||
- "[BIOS] PathPAL"
|
||||
source_ref: "src/core/bios.cpp:351-456, src/core/system.cpp:2671"
|
||||
condition: "the console region; an empty value scans SearchDirectory"
|
||||
|
||||
notes: |
|
||||
DuckStation auto-detects BIOS by MD5 hash from a flat scan of the BIOS directory.
|
||||
ref: src/core/bios.cpp:458-479 (FindBIOSImagesInDirectory, scans all files by size)
|
||||
|
||||
@@ -17,6 +17,17 @@ standalone_pools:
|
||||
"[IWADSearch.Directories] Path": ""
|
||||
"[IWADSearch.Directories] RecursivePath": ""
|
||||
|
||||
config_reads:
|
||||
- file: "gzdoom.ini"
|
||||
source_ref: "src/gameconfigfile.cpp:95-107, 942-951, src/common/platform/posix/unix/i_specialpaths.cpp:168-171"
|
||||
keys:
|
||||
- key: "[IWADSearch.Directories] Path"
|
||||
source_ref: "src/d_iwad.cpp:456-470"
|
||||
- key: "[FileSearch.Directories] Path"
|
||||
source_ref: "src/common/utility/findfile.cpp:224-260"
|
||||
- key: "[SoundfontSearch.Directories] Path"
|
||||
source_ref: "src/common/audio/music/i_soundfont.cpp:393-410"
|
||||
|
||||
notes: |
|
||||
Doom-engine source port by Christoph Oelckers. Supports Doom, Heretic,
|
||||
Hexen, Strife, Chex Quest and derived games through a unified IWAD
|
||||
|
||||
@@ -38,6 +38,45 @@ data_root:
|
||||
source_ref: "upstream src/paths.c:24-29, upstream src/paths.c:201-274"
|
||||
note: "~/.hatari is used instead when it exists and ~/.config/hatari does not. Holds hatari.cfg, hatari.nvram and auto.sav. The default tos.img is read from ../share/hatari beside the bin directory."
|
||||
|
||||
pin_build:
|
||||
- platform: emuelec
|
||||
repo: "https://github.com/EmuELEC/EmuELEC"
|
||||
revision: "v4.8"
|
||||
path: "packages/sx05re/emulators/hatarisa/package.mk"
|
||||
variable: PKG_VERSION
|
||||
value: "fda67f05188a925535fefc1b0ef24eb044a029d2"
|
||||
- platform: amberelec
|
||||
repo: "https://github.com/AmberELEC/AmberELEC"
|
||||
revision: "a21975bfb1a3af68f66e07a931b994b523e1e6e2"
|
||||
path: "packages/games/emulators/hatarisa/package.mk"
|
||||
variable: PKG_VERSION
|
||||
value: "d876db9c4b6911c059b1d9318f779f90c1c6f2d7"
|
||||
- platform: rocknix
|
||||
repo: "https://github.com/ROCKNIX/distribution"
|
||||
revision: "20261101"
|
||||
path: "projects/ROCKNIX/packages/emulators/standalone/hatarisa/package.mk"
|
||||
variable: PKG_VERSION
|
||||
value: "6da06056d89bb39777063388d82d065d9e2e31fd"
|
||||
config_reads:
|
||||
- file: "*.cfg"
|
||||
platforms: [emuelec]
|
||||
source_ref: "upstream src/options.c:1187-1193, upstream src/configuration.c:1088, 1149"
|
||||
keys:
|
||||
- key: "[ROM] szTosImageFileName"
|
||||
source_ref: "upstream src/configuration.c:481, upstream src/tos.c:975-986"
|
||||
- file: "*.cfg"
|
||||
platforms: [amberelec]
|
||||
source_ref: "upstream src/options.c:1283-1288, upstream src/configuration.c:1061, 1123"
|
||||
keys:
|
||||
- key: "[ROM] szTosImageFileName"
|
||||
source_ref: "upstream src/configuration.c:489, upstream src/tos.c:976-987"
|
||||
- file: "*.cfg"
|
||||
platforms: [rocknix]
|
||||
source_ref: "upstream src/options.c:1194-1199, upstream src/configuration.c:1050, 1111"
|
||||
keys:
|
||||
- key: "[ROM] szTosImageFileName"
|
||||
source_ref: "upstream src/configuration.c:480, upstream src/tos.c:975-986"
|
||||
|
||||
notes: |
|
||||
The main branch of libretro/hatari is the upstream Hatari tree at
|
||||
c453b85f, whose libretro target in src/retro carries the VFS, disk
|
||||
|
||||
@@ -24,6 +24,13 @@ systems: [sony-playstation-2]
|
||||
bios_directory: "pcsx2/bios/"
|
||||
resources_directory: "pcsx2/resources/"
|
||||
|
||||
config_reads:
|
||||
- file: "core options"
|
||||
source_ref: "libretro/main.cpp:506, 525-527"
|
||||
keys:
|
||||
- key: "pcsx2_bios"
|
||||
source_ref: "libretro/main.cpp:525-536, 2552-2560"
|
||||
|
||||
notes: |
|
||||
Hard fork of PCSX2 (pre-Qt, 1.7-dev era) ported to libretro, x86_64 only,
|
||||
with much of the emulator since rewritten in C89. The system directory of
|
||||
|
||||
@@ -43,6 +43,61 @@ systems:
|
||||
- snk-ngpc
|
||||
- sony-playstation
|
||||
|
||||
pin_build:
|
||||
- platform: rocknix
|
||||
repo: "https://github.com/ROCKNIX/distribution"
|
||||
revision: "20261101"
|
||||
path: "projects/ROCKNIX/packages/emulators/standalone/mednafen/package.mk"
|
||||
variable: PKG_URL
|
||||
value: "https://github.com/sydarn/mednafen/archive/refs/tags/1.32.1-chd.tar.gz"
|
||||
config_reads:
|
||||
- file: "mednafen.cfg"
|
||||
platforms: [rocknix]
|
||||
revision: "e46995e49cbaf1e9996a8e29cc5be16d7fe6d834"
|
||||
revision_from: "tag 1.32.1-chd of the sydarn/mednafen fork, the PKG_URL ROCKNIX builds"
|
||||
source_ref: "src/drivers/main.cpp:1469-1520, 1883-1974, 2249, 2405, src/general.cpp:277-300"
|
||||
keys:
|
||||
- key: "gba.bios"
|
||||
source_ref: "src/gba/GBA.cpp:3278, 772, 2472-2481"
|
||||
- key: "md.cdbios"
|
||||
source_ref: "src/md/system.cpp:755, 630-640, src/md/cd/cd.cpp:894-912, 971-982"
|
||||
condition: "CD content"
|
||||
- key: "nes.ggrom"
|
||||
source_ref: "src/nes/nes.cpp:455, 298-299, src/nes/cart.cpp:570-583"
|
||||
condition: "nes.gg 1"
|
||||
- key: "pce.cdbios"
|
||||
source_ref: "src/pce/pce.cpp:1103, 647-649"
|
||||
condition: "disc not detected as Games Express"
|
||||
- key: "pce.gecdbios"
|
||||
source_ref: "src/pce/pce.cpp:1104, 647-649"
|
||||
condition: "disc detected as Games Express"
|
||||
- key: "pce_fast.cdbios"
|
||||
source_ref: "src/pce_fast/pce.cpp:647, 476-487"
|
||||
- key: "pcfx.bios"
|
||||
source_ref: "src/pcfx/pcfx.cpp:1115, 606-611"
|
||||
- key:
|
||||
- "psx.bios_eu"
|
||||
- "psx.bios_jp"
|
||||
- "psx.bios_na"
|
||||
source_ref: "src/psx/psx.cpp:2373-2375, 1764-1775"
|
||||
condition: "the disc's region"
|
||||
- key:
|
||||
- "ss.bios_jp"
|
||||
- "ss.bios_na_eu"
|
||||
source_ref: "src/ss/ss.cpp:2441-2442, 1430-1439"
|
||||
condition: "not ST-V, by SMPC area"
|
||||
- key:
|
||||
- "ss.bios_stv_eu"
|
||||
- "ss.bios_stv_jp"
|
||||
- "ss.bios_stv_na"
|
||||
source_ref: "src/ss/ss.cpp:2444-2446, 1420-1439"
|
||||
condition: "ST-V cart, by area"
|
||||
- key:
|
||||
- "ss.cart.kof95_path"
|
||||
- "ss.cart.ultraman_path"
|
||||
source_ref: "src/ss/ss.cpp:2477-2478, 1811-1840, 1320-1350, 1389-1396"
|
||||
condition: "cart type KOF95 or ULTRAMAN"
|
||||
|
||||
notes: |
|
||||
Multi-system emulator by the Mednafen Team, the upstream of the beetle_* and
|
||||
mednafen_* libretro cores, which are forks of individual modules. A module is
|
||||
|
||||
@@ -28,6 +28,58 @@ data_root:
|
||||
source_ref: "upstream src/frontend/qt_sdl/main.cpp:182-184, 196-200, 206-211"
|
||||
note: "portable beside the executable when that folder exists"
|
||||
|
||||
pin_build:
|
||||
- platform: rocknix
|
||||
repo: "https://github.com/ROCKNIX/distribution"
|
||||
revision: "20261101"
|
||||
path: "projects/ROCKNIX/packages/emulators/standalone/melonds-sa/package.mk"
|
||||
variable: PKG_VERSION
|
||||
value: "906e9ebb27da8c6a715cd7abab4abfe8a8d29427"
|
||||
config_reads:
|
||||
- file: "melonDS.ini"
|
||||
platforms: [rocknix]
|
||||
source_ref: "upstream src/frontend/qt_sdl/main.cpp:366, upstream src/frontend/qt_sdl/Config.cpp:682-774, 777-783, 785-795, upstream src/frontend/qt_sdl/Platform.cpp:144-166, ROCKNIX projects/ROCKNIX/packages/emulators/standalone/melonds-sa/patches/001-default-config.patch:8-13, ROCKNIX projects/ROCKNIX/packages/emulators/standalone/melonds-sa/patches/003-hotkeys.patch:41-76"
|
||||
keys:
|
||||
- key: "BIOS9Path"
|
||||
source_ref: "upstream src/frontend/qt_sdl/Config.cpp:238, 240, upstream src/frontend/qt_sdl/EmuInstance.cpp:855-876, 1261-1263"
|
||||
condition: "ExternalBIOSEnable=1"
|
||||
- key: "BIOS7Path"
|
||||
source_ref: "upstream src/frontend/qt_sdl/Config.cpp:238, 241, upstream src/frontend/qt_sdl/EmuInstance.cpp:878-898, 1265-1267"
|
||||
condition: "ExternalBIOSEnable=1"
|
||||
- key: "FirmwarePath"
|
||||
source_ref: "upstream src/frontend/qt_sdl/Config.cpp:238, 242, upstream src/frontend/qt_sdl/EmuInstance.cpp:992-1016, 1269"
|
||||
condition: "ExternalBIOSEnable=1 and ConsoleType=0"
|
||||
- key: "DSiNANDPath"
|
||||
source_ref: "upstream src/frontend/qt_sdl/Config.cpp:227, 249, upstream src/frontend/qt_sdl/EmuInstance.cpp:1039-1043, 1227, 1312-1322"
|
||||
condition: "ConsoleType=1"
|
||||
- file: "melonDS.toml"
|
||||
platforms: [emudeck, retrobat]
|
||||
revision: "b86390e4428bf38ce4c1ce0e9ca446d6d25955e8"
|
||||
revision_from: "melonDS 1.1: the Flathub manifest net.kuribo64.melonDS at e5ce4504 builds it, and RetroBat's melonDS.exe names it"
|
||||
source_ref: "upstream src/frontend/qt_sdl/main.cpp:196-213, 328, upstream src/frontend/qt_sdl/Config.cpp:42, 785-799"
|
||||
keys:
|
||||
- key: "[DS] BIOS9Path"
|
||||
source_ref: "upstream src/frontend/qt_sdl/EmuInstance.cpp:868-889, 1277"
|
||||
condition: "[Emu] ExternalBIOSEnable = true"
|
||||
- key: "[DS] BIOS7Path"
|
||||
source_ref: "upstream src/frontend/qt_sdl/EmuInstance.cpp:891-911"
|
||||
condition: "[Emu] ExternalBIOSEnable = true"
|
||||
- key: "[DS] FirmwarePath"
|
||||
source_ref: "upstream src/frontend/qt_sdl/EmuInstance.cpp:1013-1031, 1285"
|
||||
condition: "[Emu] ExternalBIOSEnable = true and ConsoleType = 0"
|
||||
- key: "[DSi] BIOS9Path"
|
||||
source_ref: "upstream src/frontend/qt_sdl/EmuInstance.cpp:913-938, 1328-1336"
|
||||
condition: "[Emu] ConsoleType = 1"
|
||||
- key: "[DSi] BIOS7Path"
|
||||
source_ref: "upstream src/frontend/qt_sdl/EmuInstance.cpp:940-965, 1328-1332"
|
||||
condition: "[Emu] ConsoleType = 1"
|
||||
- key: "[DSi] FirmwarePath"
|
||||
source_ref: "upstream src/frontend/qt_sdl/EmuInstance.cpp:1013-1029, 1285"
|
||||
condition: "[Emu] ConsoleType = 1"
|
||||
- key: "[DSi] NANDPath"
|
||||
source_ref: "upstream src/frontend/qt_sdl/EmuInstance.cpp:1064-1068, 1338-1340"
|
||||
condition: "[Emu] ConsoleType = 1"
|
||||
|
||||
notes: |
|
||||
FreeBIOS fallback for DS mode (NTR), while DSi mode requires all native files.
|
||||
Libretro fork based on melonDS ~0.9.x era, validates size only.
|
||||
|
||||
@@ -24,6 +24,14 @@ cores:
|
||||
systems:
|
||||
- nintendo-gba
|
||||
|
||||
config_reads:
|
||||
- file: "/storage/.config/nanoboyadvance/config.toml"
|
||||
platforms: [rocknix]
|
||||
source_ref: "src/platform/sdl/main.cpp:293, src/platform/core/src/config.cpp:16-31"
|
||||
keys:
|
||||
- key: "[general] bios_path"
|
||||
source_ref: "src/platform/core/src/config.cpp:36, src/platform/sdl/main.cpp:177-191, src/platform/core/src/loader/bios.cpp:19-46"
|
||||
|
||||
notes: |
|
||||
Game Boy Advance emulator. ROCKNIX builds the SDL2 frontend only
|
||||
(PLATFORM_SDL2=ON, PLATFORM_QT=OFF).
|
||||
|
||||
@@ -45,6 +45,37 @@ data_root:
|
||||
source_ref: "ui/xemu-settings.cc:51-63, 73-92"
|
||||
note: "xemu.toml beside the executable makes its folder the root"
|
||||
|
||||
pin_build:
|
||||
- platform: rocknix
|
||||
repo: "https://github.com/ROCKNIX/distribution"
|
||||
revision: "20261101"
|
||||
path: "projects/ROCKNIX/packages/emulators/standalone/xemu-sa/package.mk"
|
||||
variable: PKG_VERSION
|
||||
value: "cbffb57d084c70351a596e99e32a8b73e0c5eabf"
|
||||
config_reads:
|
||||
- file: "xemu.toml"
|
||||
platforms: [rocknix]
|
||||
source_ref: "ui/xemu.c:1314-1325, ui/xemu-settings.cc:65-71, 94-104, 158-207"
|
||||
keys:
|
||||
- key: "[sys.files] bootrom_path"
|
||||
source_ref: "system/vl.c:2983-3016"
|
||||
- key: "[sys.files] flashrom_path"
|
||||
source_ref: "system/vl.c:3041-3054"
|
||||
condition: "[general] show_welcome false"
|
||||
- key: "[sys.files] eeprom_path"
|
||||
source_ref: "system/vl.c:2909-2949, 3030-3039"
|
||||
- key: "[sys.files] hdd_path"
|
||||
source_ref: "system/vl.c:3060-3074"
|
||||
- file: "xemu.toml"
|
||||
platforms: [retrobat]
|
||||
revision: "fc24584ce88f0915ad7f04775bb7712c2e3f49ee"
|
||||
revision_from: "xemu.exe 0.8.136 in RetroBat's stable xemu.7z, 2026-11-10"
|
||||
source_ref: "ui/xemu.c:1325, ui/xemu-settings.cc:51-63, 73-92, 94-104, 158-207"
|
||||
keys:
|
||||
- key: "[sys.files] flashrom_path"
|
||||
source_ref: "system/vl.c:3041-3054"
|
||||
condition: "[general] show_welcome false"
|
||||
|
||||
notes: |
|
||||
Full-system Xbox emulator built on QEMU. The libretro core is built from
|
||||
libretro's xemu-libretro tree on its libretro branch, which merges
|
||||
|
||||
@@ -29,6 +29,57 @@ standalone_pools:
|
||||
rompath: ""
|
||||
"-rompath": ""
|
||||
|
||||
config_reads:
|
||||
- file: "xroar.conf"
|
||||
source_ref: "src/xroar.c:882-909, 975-993"
|
||||
keys:
|
||||
- key: "rompath"
|
||||
source_ref: "src/xroar.c:3266, src/romlist.c:125-140"
|
||||
- key:
|
||||
- "romlist dragon"
|
||||
- "romlist d64_1"
|
||||
- "romlist d64_2"
|
||||
- "romlist d32"
|
||||
- "romlist d200e_1"
|
||||
- "romlist d200e_2"
|
||||
- "romlist dragon64"
|
||||
- "romlist dragon64_alt"
|
||||
- "romlist dragon32"
|
||||
- "romlist dragon200e"
|
||||
- "romlist dragon200e_alt"
|
||||
- "romlist dragon200e_charset"
|
||||
- "romlist dragonpro_boot"
|
||||
- "romlist dragonpro_basic"
|
||||
- "romlist coco"
|
||||
- "romlist coco_ext"
|
||||
- "romlist deluxecoco"
|
||||
- "romlist deluxecoco1"
|
||||
- "romlist deluxecoco2"
|
||||
- "romlist deluxecoco3"
|
||||
- "romlist mx1600"
|
||||
- "romlist mx1600ext"
|
||||
- "romlist coco3"
|
||||
- "romlist coco3p"
|
||||
- "romlist glenside_ide"
|
||||
- "romlist mc10"
|
||||
- "romlist alice"
|
||||
- "romlist dragondos"
|
||||
- "romlist dosplus"
|
||||
- "romlist superdos"
|
||||
- "romlist cumana"
|
||||
- "romlist dragondos_compat"
|
||||
- "romlist rsdos"
|
||||
- "romlist delta"
|
||||
- "romlist rsdos_becker"
|
||||
- "romlist mcx128"
|
||||
- "romlist mcx128_azerty"
|
||||
source_ref: "src/xroar.c:646-731, 3267, src/romlist.c:125-140"
|
||||
- file: "command line"
|
||||
source_ref: "src/xroar.c:1007"
|
||||
keys:
|
||||
- key: "-rompath"
|
||||
source_ref: "src/xroar.c:3266, src/romlist.c:125-140"
|
||||
|
||||
notes: |
|
||||
XRoar by Ciaran Anscomb emulates Dragon 32/64, Tandy CoCo 1/2/3,
|
||||
MC-10, Alice, and clones (MX-1600, CP-400, Dragon 200-E, Deluxe CoCo).
|
||||
|
||||
@@ -0,0 +1,330 @@
|
||||
"""A launcher record resting on a config file binds only when its chain holds.
|
||||
|
||||
The platform's code installs the file (installs), its launch code was read
|
||||
for what replaces it (overrides), and the emulator's profile says where the
|
||||
build the platform ships loads the file and reads each key (config_reads).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import tests # noqa: F401 offline, scratch under tmp/, the suite's own cache
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts"))
|
||||
|
||||
import yaml # noqa: E402
|
||||
|
||||
from common import load_platform_config # noqa: E402
|
||||
from launchers import ( # noqa: E402
|
||||
bound_launchers,
|
||||
config_evidence,
|
||||
config_target,
|
||||
handed_directories,
|
||||
launcher_places,
|
||||
launcher_unproven,
|
||||
)
|
||||
from profile_sync import _check_build_refs, shipped_build_holders # noqa: E402
|
||||
from scraper.retrobat_launchers import _choices_apart # noqa: E402
|
||||
from scraper.shell_launchers import ( # noqa: E402
|
||||
LauncherPatternMissing,
|
||||
Script,
|
||||
config_placement,
|
||||
config_ref,
|
||||
is_feature_ref,
|
||||
)
|
||||
from validate_schemas import ( # noqa: E402
|
||||
_config_reads_without_build,
|
||||
_config_records_without_evidence,
|
||||
)
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def record(**fields: object) -> dict:
|
||||
"""A ROCKNIX-like DuckStation record citing its shipped settings.ini."""
|
||||
base = {
|
||||
"emulator": "duck", "build": "standalone", "kind": "scans_dir", "names": [],
|
||||
"search_dir": "/storage/roms/bios",
|
||||
"passes_to": "settings.ini [BIOS] SearchDirectory = /storage/roms/bios, [BIOS] PathPAL unset",
|
||||
"installs": {"path": "/storage/.config/duck/settings.ini", "source_ref": "setup.sh:13"},
|
||||
"overrides": [],
|
||||
"source_ref": "duck/config/settings.ini:4, duck/package.mk:33",
|
||||
}
|
||||
return {**base, **fields}
|
||||
|
||||
|
||||
def profile(**fields: object) -> dict:
|
||||
base = {
|
||||
"emulator": "Duck", "type": "standalone", "cores": ["duck"],
|
||||
"standalone_directories": ["[BIOS] SearchDirectory"],
|
||||
"config_reads": [{
|
||||
"file": "settings.ini", "source_ref": "src/core.cpp:10",
|
||||
"keys": [
|
||||
{"key": "[BIOS] SearchDirectory", "source_ref": "src/settings.cpp:20"},
|
||||
{"key": ["[BIOS] PathPAL", "[BIOS] PathNTSCU"], "source_ref": "src/bios.cpp:30"},
|
||||
],
|
||||
}],
|
||||
}
|
||||
return {**base, **fields}
|
||||
|
||||
|
||||
class ConfigRefs(unittest.TestCase):
|
||||
def test_config_option_and_feature_files_are_cited_apart(self) -> None:
|
||||
ref = "a/settings.ini:4, 6, a/start.sh:3, b/MAME.opt:19, .emulationstation/es_features.cfg:9"
|
||||
self.assertEqual(
|
||||
config_ref(ref),
|
||||
["a/settings.ini:4, 6", "b/MAME.opt:19", ".emulationstation/es_features.cfg:9"],
|
||||
)
|
||||
self.assertEqual([is_feature_ref(p) for p in config_ref(ref)], [False, True, True])
|
||||
|
||||
def test_passes_to_names_the_file_and_its_keys(self) -> None:
|
||||
cases = {
|
||||
"settings.ini [BIOS] SearchDirectory (-settings), [BIOS] PathNTSCU, PathPAL unset":
|
||||
("settings.ini", ["[BIOS] SearchDirectory", "[BIOS] PathNTSCU", "[BIOS] PathPAL"]),
|
||||
"melonDS.toml [DS] BIOS9Path [DSi] NANDPath, first file whose name holds the region":
|
||||
("melonDS.toml", ["[DS] BIOS9Path", "[DSi] NANDPath"]),
|
||||
"settings.ini [BIOS] PathNTSCJ = PathNTSCU = <value>":
|
||||
("settings.ini", ["[BIOS] PathNTSCJ", "[BIOS] PathNTSCU"]),
|
||||
"AmigaA500-default.uae kickstart_rom_file, $(FILE_PATH) = /storage/k/":
|
||||
("AmigaA500-default.uae", ["kickstart_rom_file", "$(FILE_PATH)"]),
|
||||
"command line -rompath bios/coco": ("command line", ["-rompath"]),
|
||||
"core option pcsx2_bios": ("core options", ["pcsx2_bios"]),
|
||||
}
|
||||
for passes_to, expected in cases.items():
|
||||
with self.subTest(passes_to=passes_to):
|
||||
self.assertEqual(config_target({"passes_to": passes_to}), expected)
|
||||
core = {"build": "libretro", "kind": "core_option", "passes_to": "hatarib_tos = x/<value>"}
|
||||
self.assertEqual(config_target(core), ("core options", ["hatarib_tos"]))
|
||||
|
||||
def test_a_record_naming_no_file_takes_the_config_it_installs(self) -> None:
|
||||
romlist = record(
|
||||
passes_to="romlist coco",
|
||||
installs={"path": "$xroar_config", "source_ref": "prepare.sh:13"},
|
||||
source_ref="xroar/rd_config/xroar.conf:305, xroar/prepare.sh:13",
|
||||
)
|
||||
self.assertEqual(config_target(romlist), ("xroar.conf", ["romlist coco"]))
|
||||
|
||||
|
||||
class Evidence(unittest.TestCase):
|
||||
profiles = {"duck": profile()}
|
||||
|
||||
def test_a_record_resting_on_code_holds(self) -> None:
|
||||
code = {"emulator": "duck", "kind": "fixed_name", "source_ref": "start.sh:3"}
|
||||
self.assertTrue(config_evidence(code, {}).proven)
|
||||
|
||||
def test_the_whole_chain_holds(self) -> None:
|
||||
evidence = config_evidence(record(), self.profiles, "rocknix")
|
||||
self.assertTrue(evidence.proven, evidence.missing)
|
||||
self.assertEqual(evidence.readers, ("duck",))
|
||||
|
||||
def test_each_missing_link_is_named(self) -> None:
|
||||
bare = {k: v for k, v in record().items() if k not in ("installs", "overrides")}
|
||||
missing = config_evidence(bare, self.profiles).missing
|
||||
self.assertEqual(len(missing), 2)
|
||||
self.assertTrue(missing[0].startswith("installs"))
|
||||
self.assertTrue(missing[1].startswith("overrides"))
|
||||
|
||||
def test_a_profile_that_reads_no_such_file_proves_nothing(self) -> None:
|
||||
missing = config_evidence(record(), {"duck": profile(config_reads=[])}).missing
|
||||
self.assertEqual(missing, ("config_reads: an emulator that loads settings.ini",))
|
||||
|
||||
def test_a_key_the_build_does_not_read_is_named(self) -> None:
|
||||
unread = record(passes_to="settings.ini [BIOS] PathNTSCJ")
|
||||
self.assertEqual(
|
||||
config_evidence(unread, self.profiles).missing,
|
||||
("config_reads: no read of [BIOS] PathNTSCJ",),
|
||||
)
|
||||
|
||||
def test_a_handle_with_its_code_ref_reads_the_key(self) -> None:
|
||||
handled = profile(
|
||||
config_reads=[{"file": "settings.ini", "source_ref": "src/core.cpp:10", "keys": [
|
||||
{"key": "[BIOS] PathPAL", "source_ref": "src/bios.cpp:30"}]}],
|
||||
standalone_directories=[
|
||||
{"handle": "[BIOS] SearchDirectory", "source_ref": "src/settings.cpp:20"}
|
||||
],
|
||||
)
|
||||
self.assertTrue(config_evidence(record(), {"duck": handled}).proven)
|
||||
|
||||
def test_an_option_list_is_never_the_source(self) -> None:
|
||||
listed = record(source_ref="gen.cs:3, .emulationstation/es_features.cfg:9")
|
||||
self.assertIn(
|
||||
"an option list cited as source, not as choices_from",
|
||||
config_evidence(listed, self.profiles).missing,
|
||||
)
|
||||
|
||||
def test_an_option_choice_needs_the_emulator_side_too(self) -> None:
|
||||
chosen = {
|
||||
"emulator": "duck", "kind": "core_option", "passes_to": "settings.ini [BIOS] PathPAL = <value>",
|
||||
"choices_from": "es_features.cfg:9", "source_ref": "gen.cs:3",
|
||||
}
|
||||
self.assertTrue(config_evidence(chosen, self.profiles).proven)
|
||||
self.assertFalse(config_evidence(chosen, {"duck": profile(config_reads=[])}).proven)
|
||||
|
||||
def test_reads_written_for_a_shipped_build_apply_to_its_platform_only(self) -> None:
|
||||
built = profile(
|
||||
source_commit="a" * 40,
|
||||
pin_build=[{"platform": "rocknix", "value": "b" * 40}],
|
||||
config_reads=[{**profile()["config_reads"][0], "platforms": ["rocknix"]}],
|
||||
)
|
||||
self.assertTrue(config_evidence(record(), {"duck": built}, "rocknix").proven)
|
||||
self.assertFalse(config_evidence(record(), {"duck": built}, "emuelec").proven)
|
||||
|
||||
def test_reads_at_the_pin_skip_a_platform_shipping_another_build(self) -> None:
|
||||
other = profile(source_commit="a" * 40, pin_build=[{"platform": "rocknix", "value": "b" * 40}])
|
||||
self.assertFalse(config_evidence(record(), {"duck": other}, "rocknix").proven)
|
||||
self.assertTrue(config_evidence(record(), {"duck": other}, "emuelec").proven)
|
||||
|
||||
|
||||
class Gate(unittest.TestCase):
|
||||
def config(self, *records: dict) -> dict:
|
||||
return {"_key": "rocknix", "base_destination": "bios", "launchers": list(records)}
|
||||
|
||||
def test_an_unproven_record_hands_no_directory(self) -> None:
|
||||
proven = handed_directories(self.config(record()), {"duck": profile()})
|
||||
self.assertEqual([h.folder for h in proven], [""])
|
||||
self.assertEqual(handed_directories(self.config(record()), {"duck": profile(config_reads=[])}), [])
|
||||
|
||||
def test_an_unproven_record_places_no_file(self) -> None:
|
||||
named = record(
|
||||
kind="fixed_name", names=["tos.img"], passes_to="settings.ini [BIOS] PathPAL",
|
||||
)
|
||||
self.assertEqual(len(launcher_places(self.config(named), {"duck": profile()})), 1)
|
||||
self.assertEqual(launcher_places(self.config(named), {"duck": profile(config_reads=[])}), [])
|
||||
|
||||
def test_the_unproven_are_reported_with_what_they_lack(self) -> None:
|
||||
config = self.config({"emulator": "x", "kind": "links", "source_ref": "a.sh:1"}, record())
|
||||
self.assertEqual(launcher_unproven({"rocknix": config}, {"duck": profile()}), [])
|
||||
(row,) = launcher_unproven({"rocknix": config}, {"duck": profile(config_reads=[])})
|
||||
self.assertEqual((row["platform"], row["index"], row["emulator"]), ("rocknix", 1, "duck"))
|
||||
self.assertEqual(row["config"], ["duck/config/settings.ini:4"])
|
||||
self.assertEqual(len(bound_launchers(config, {"duck": profile(config_reads=[])})), 1)
|
||||
|
||||
|
||||
class StartScripts(unittest.TestCase):
|
||||
SCRIPT = (
|
||||
'CONF_DIR="/storage/.config/duck"\n'
|
||||
'CONF_FILE="${CONF_DIR}/settings.ini"\n'
|
||||
'[ ! -d "${CONF_DIR}" ] && cp -r /usr/config/duck /storage/.config\n'
|
||||
'if [ ! -f "${CONF_FILE}" ]; then\n'
|
||||
' cp /usr/config/duck/settings.ini ${CONF_FILE}\n'
|
||||
'fi\n'
|
||||
"sed -i '/^AspectRatio/c\\\\AspectRatio = 4:3' ${CONF_FILE}\n"
|
||||
"sed -i '/^PathPAL/c\\\\PathPAL = x.bin' ${CONF_FILE}\n"
|
||||
'cp /usr/config/duck/other.ini ${CONF_DIR}/ >/dev/null 2>&1\n'
|
||||
)
|
||||
|
||||
def test_a_guarded_copy_keeps_the_file_and_a_key_rewrite_is_an_override(self) -> None:
|
||||
placement = config_placement(
|
||||
Script("start.sh", self.SCRIPT), "/storage/.config/duck/settings.ini", ["[BIOS] PathPAL"]
|
||||
)
|
||||
self.assertEqual(placement.install, {3, 5})
|
||||
self.assertTrue(placement.kept_if_present)
|
||||
self.assertEqual(placement.overrides, {8})
|
||||
|
||||
def test_a_copy_at_each_launch_replaces_the_file(self) -> None:
|
||||
script = Script("start.sh", 'cp /usr/config/duck/settings.ini /storage/.config/duck/settings.ini\n')
|
||||
self.assertFalse(config_placement(script, "/storage/.config/duck/settings.ini").kept_if_present)
|
||||
|
||||
def test_a_script_installing_nothing_raises(self) -> None:
|
||||
with self.assertRaises(LauncherPatternMissing):
|
||||
config_placement(Script("start.sh", "echo hi\n"), "/storage/.config/duck/settings.ini")
|
||||
|
||||
def test_retrobat_moves_the_option_list_to_choices_from(self) -> None:
|
||||
moved = _choices_apart({
|
||||
"emulator": "x", "passes_to": "p",
|
||||
"source_ref": "Gen.cs:3-4, .emulationstation/es_features.cfg:9-12",
|
||||
})
|
||||
self.assertEqual(moved["source_ref"], "Gen.cs:3-4")
|
||||
self.assertEqual(moved["choices_from"], ".emulationstation/es_features.cfg:9-12")
|
||||
self.assertEqual(list(moved)[-1], "source_ref")
|
||||
|
||||
|
||||
class Invariants(unittest.TestCase):
|
||||
def test_a_config_record_without_its_platform_links_is_an_error(self) -> None:
|
||||
path = REPO_ROOT / "platforms" / "x.yml"
|
||||
bare = {k: v for k, v in record().items() if k not in ("installs", "overrides")}
|
||||
listed = record(source_ref="gen.cs:3, es_features.yml:9")
|
||||
errors = _config_records_without_evidence(path, {"launchers": [record(), bare, listed]})
|
||||
self.assertEqual(len(errors), 2)
|
||||
self.assertIn("without installs and overrides", errors[0])
|
||||
self.assertIn("choices_from holds it", errors[1])
|
||||
|
||||
def test_reads_naming_a_platform_need_its_build(self) -> None:
|
||||
path = REPO_ROOT / "emulators" / "x.yml"
|
||||
reads = [{"file": "a.ini", "platforms": ["rocknix"], "source_ref": "a:1", "keys": []}]
|
||||
self.assertEqual(len(_config_reads_without_build(path, {"config_reads": reads})), 1)
|
||||
self.assertEqual(_config_reads_without_build(
|
||||
path, {"config_reads": reads, "pin_build": [{"platform": "rocknix"}]}
|
||||
), [])
|
||||
pinned = [{**reads[0], "revision": "c" * 40, "revision_from": "the exe"}]
|
||||
self.assertEqual(_config_reads_without_build(path, {"config_reads": pinned}), [])
|
||||
|
||||
|
||||
class BuildRefs(unittest.TestCase):
|
||||
def test_reads_for_a_shipped_build_are_read_at_that_build(self) -> None:
|
||||
document = {
|
||||
"pin_build": [{"platform": "rocknix", "value": "b" * 40}],
|
||||
"config_reads": [{
|
||||
"file": "a.ini", "platforms": ["rocknix"], "source_ref": "src/a.c:2",
|
||||
"keys": [{"key": "k", "source_ref": "src/a.c:9, ROCKNIX x.patch:1"}],
|
||||
}],
|
||||
}
|
||||
held = shipped_build_holders(document)
|
||||
self.assertEqual(len(held), 2)
|
||||
|
||||
class View:
|
||||
repo, field = "repo", "source"
|
||||
|
||||
class Citation:
|
||||
def __init__(self, ref: str, field: str) -> None:
|
||||
self.ref, self.field = ref, field
|
||||
|
||||
asked: list[tuple[str, str]] = []
|
||||
|
||||
def fetch(_repo: str, revision: str, path: str) -> list[str] | None:
|
||||
asked.append((revision, path))
|
||||
return ["line"] * 5 if path == "src/a.c" else None
|
||||
|
||||
rows = _check_build_refs(
|
||||
document,
|
||||
[(Citation("src/a.c:2", "c"), document["config_reads"][0]),
|
||||
(Citation("src/a.c:9, ROCKNIX x.patch:1", "k"), document["config_reads"][0])],
|
||||
[View()], fetch,
|
||||
)
|
||||
self.assertEqual([r["status"] for r in rows], ["BUILD_OK", "BUILD_GONE"])
|
||||
self.assertTrue(all(revision == "b" * 40 for revision, _ in asked))
|
||||
self.assertNotIn(("b" * 40, "ROCKNIX x.patch"), asked)
|
||||
|
||||
|
||||
class RepositoryRecords(unittest.TestCase):
|
||||
"""The placement chains the audit of 2026-11-10 found moving files."""
|
||||
|
||||
def test_the_chains_that_move_placements_still_bind(self) -> None:
|
||||
platforms = REPO_ROOT / "platforms"
|
||||
cases = (
|
||||
("rocknix", "armsx2", "/storage/roms/bios/armsx2"),
|
||||
("retrodeck", "gzdoom", "$roms_path/doom"),
|
||||
("retrodeck", "xroar", "$roms_path/coco"),
|
||||
("retrobat", "xroar", "bios/coco"),
|
||||
)
|
||||
for platform, emulator, directory in cases:
|
||||
with self.subTest(platform=platform, emulator=emulator):
|
||||
handed = handed_directories(load_platform_config(platform, str(platforms)))
|
||||
self.assertIn(
|
||||
directory, {h.directory for h in handed if h.emulator == emulator}
|
||||
)
|
||||
|
||||
def test_every_config_record_carries_its_platform_links(self) -> None:
|
||||
for path in sorted((REPO_ROOT / "platforms").glob("*.yml")):
|
||||
if path.name.startswith("_"):
|
||||
continue
|
||||
with self.subTest(platform=path.stem):
|
||||
document = yaml.safe_load(path.read_text(encoding="utf-8"))
|
||||
self.assertEqual(_config_records_without_evidence(path, document), [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user