verify.py --emulator fbneo --strict > log 2>&1 put the ERROR verdict on
the first line of the log: redirected, stdout is block-buffered and
stderr is not, and run_cli flushed stdout only after main returned.
run_cli now sets stdout to line buffering, so every tool it runs keeps
the two streams in the order they were written.
Geargrafx drops a 512-byte header before its crc32 (src/media.cpp:754-773
at 7c447b0b), and its profile lists both sizes. slots compared the crc32
of the whole file, so EmuELEC's headered syscard3.pce read as contested.
Without --verbose each missing core file was followed by a bare '[size]'
line that told the reader nothing. It now reads 'validates size', the
verbose wording without the expected values.
'Bundled with their emulator, not collected: 154' listed the 14 required
firmware names and nothing said the rest existed. The line now ends with
'139 more, --verbose lists them', as the Core files line does.
Every profile is loaded whatever the command, so one misindented key in
an unrelated profile stopped verify.py --emulator handy and generate_pack
on a 37-line yaml traceback. The sources common.py reads (profiles,
platform files, registry, shared groups, targets) now raise
SourceUnreadable, which run_cli prints on one line with the file, the
line and the validate_schemas command. It is not a FileNotFoundError:
ten callers skip a platform whose file is absent, and a damaged one must
not be skipped the same way.
MiSTer and BizHawk declare cores: []. --region, --one-per-slot and
--no-game-data read the profiles of the cores a platform runs, so their
packs and manifests withdrew nothing under a name and README that said
they had. generate_pack and verify now refuse the flags for a named
platform and leave it out under --all.
dsi_bios7.bin and dsi_bios9.bin hold the DSi Panda devkit boot ROMs, eMMC
key-Y zeroed. Every md5 and crc32 declared under those names designates
a retail dump in the same directory, yet hashless entries (RetroBat,
dsperate) got the devkit ROMs by name. by_proven_name maps such a name to
the proven primaries beside it. kick13.rom, dsi_firmware.bin and
spectrum.zip follow the same rule.
--db databse.json, with database.json in the same folder, was told to run
generate_db --force --output databse.json: a rescan of the whole
collection into a second file under the typo. load_database now names the
closest .json in that folder first, and gives the rebuild command only
when none is close.
A mistyped --system said '--list-systems lists all 579' and the listing
prints 532: the hint counted every spelling across profiles, and
system_index merges the ones that differ in case or separator before
printing. Both verify.py and generate_pack.py now pass that count to
suggest_names, whose listed parameter exists for this case.
The closing summary of verify --all grouped platform to names: sfiii2a.zip,
missing on 15 platforms, was printed 15 times on a 1 060-character line and
counted 24 files for 10 distinct ones. It now groups by file and names the
platforms by the shorter side (every platform but BizHawk, MinUI, MiSTer
FPGA).
Only generate_pack.py and pipeline.py checked the interpreter. verify.py,
slots.py, validate_pr.py, cross_reference.py and the probe tools started
under 3.8 and stopped halfway on a str.removeprefix AttributeError. The
check now lives in common.py, which every build script imports, and in
core_probe.py and region_check.py, which do not. generate_site.py imports
common before siterender, which raised a TypeError at load under 3.8.
Six helpers that write a pack member declared zipfile.ZipFile while every
call site also passes the PackRecord the pipeline builds emulator and
narrowed packs with. mypy reported the 19 call sites as arg-type errors.
With the union in the signature a helper that calls writestr or write
without its isinstance branch is a union-attr error in CI, instead of an
AttributeError in the pipeline's record pass.
_ships and _emulator_ships resolved without the data directories, the
archive index and the slot override the builder uses: 400 platform
declarations and 178 emulator entries read as missing while the pack
held them.
The v4.8 release publishes four images (Amlogic-ng, GameForce,
OdroidGoAdvance, OdroidM1, read from its asset names). The metapackage
(packages/sx05re/emuelec/package.mk:8-77) builds the S922X cores, dolphinSA
and mame only on Amlogic-ng, Amlogic-no, RK356x and OdroidM1, and removes
duckstation on the handhelds with a sed that replaces the first match only:
pcsx_rearmed, written twice, keeps its 64-bit build. Each package is mapped
to its cores by the .so or program its install step copies, PKG_ARCH is
applied as scripts/build:28-30 does, and es_systems.cfg is edited per
device as emuelec-emulationstation/package.mk:114-143 does. Amlogic-ng and
OdroidM1 list 124 cores, the handhelds 117.
RetroPie was the only platform with status: archived, which kept it out
of verify --all, slots, the pipeline and list_platforms unless
--include-archived was typed. release_pack already decides which packs a
release publishes and the installer serves every platform, so the status
set nothing apart. The field, its schema entry and the flag are gone, and
RetroPie is covered by every full run like any other platform.
check_source_paths read the trees profiles pin from source and upstream
only, so the two platform trees the record now holds for pin_build
files read as orphaned and the record as stale.
reading-reports quotes a RetroDECK run, which now prints the bundled count and 30 missing game data instead of 38. The comment introducing the bundled names also loses its semicolon.
Walking the systems sorted reordered the declarations doubled.py
reports from, so the export report named the CoCo reader first. The
declarations keep the platform's order again, and the packed file is
picked from the sorted walk the builder makes.
A search for gba_bios.bin or scph5500.bin landed on a page described as
"It reads 4 files, none of them required". The snippet now names the
console and the files, required first, in the longest form that fits.
Every source link on the site leads to a path the source record saw at
a commit. The Build file row linked pin_build files unchecked, eight of
them at commits the record did not hold. build_source_paths now records
the build files read at a commit, and the row links only those: a tag
can move and stays plain text. The record run also picked up two cited
paths it had not seen before (pom2 CMakeLists.txt, pcem configure.ac).
generate_manifest called slot_choices, and pack_overrides called it again with the same five arguments. pack_overrides takes the choices when the caller holds them. Measured on generate_pack.py --all --manifest --offline: 48 calls and 7.0 s in slot_choices before, 24 calls and 4.3 s after (wall 45.7 s and 42.4 s, one run each on a loaded host). The manifests written are identical.
SelectionIndex.build and system_group called _norm_system_id 1.7 million times per manifest run for about a thousand ids, each through the manufacturer prefix loop. The function reads only its argument and two constant tables, so its answer is cached. Measured on the call volume of one manifest run (630 ids, 1,686,618 calls): 1.53 s uncached, 0.07 s cached. The end-to-end manifest run moves inside its own noise on this host (45.9 to 50.6 s across four runs).