From a37af8e42e38556e18de19f8d2197c97ab3590c0 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:06:49 +0200 Subject: [PATCH] docs: readme installer options and plain wording The quick install block gains the PowerShell form that passes options and a link to the installer page. The collection size uses the GB format of the download table and the site, counts get separators, and the sentences about RetroArch's existence check and the method describe the code instead of judging documentation. --- README.md | 11 +++++++---- scripts/generate_readme.py | 24 +++++++++++++---------- scripts/generate_site.py | 2 +- tests/test_doc_pages.py | 40 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 3db02361..70f6724f 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,13 @@ curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | # SD card mounted on a PC: --dest is the BIOS folder on the card # (RetroArch on Switch: retroarch/cores/system, on Android: RetroArch/system) curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --platform retroarch --dest /path/to/sdcard/retroarch/cores/system + +# Options in PowerShell: anything after | iex goes to iex, so the script runs as a block +&([scriptblock]::Create((irm https://raw.githubusercontent.com/Abdess/retrobios/main/install.ps1))) --check ``` The script auto-detects your platform, downloads only missing files, and verifies checksums. +Every option, and what the installer detects and writes, is on the [installer page](https://abdess.github.io/retrobios/wiki/installer/#passing-options). ## Download BIOS packs @@ -65,7 +69,7 @@ The RetroDECK pack already carries its own `bios/` folder, so it extracts into ` BIOS, firmware, and system files for consoles from Atari to PlayStation 3. These are the files an emulator loads from disk instead of carrying inside itself. Some are required to boot a system, others improve accuracy or unlock a feature, and the packs carry both. -Each file is checked the way your platform checks it. Most compare a checksum, the fingerprint of a file's contents, which catches a corrupt or unexpected copy. RetroArch, Lakka and RetroPie only look for the filename, because that is all their code does: the Coverage table says which applies to you. Independently of that, the collection records five fingerprints per file, and wherever an emulator's code states an expected size or hash, that value is read from its source and rechecked here. +Each file is checked the way your platform checks it. Most compare a checksum, the fingerprint of a file's contents, which catches a corrupt or unexpected copy. RetroArch, Lakka and RetroPie check that the file is present under its name without reading its contents (`path_is_valid` in RetroArch's `core_info.c`): the Coverage table says which applies to you. Independently of that, the collection records five fingerprints per file, and wherever an emulator's code states an expected size or hash, that value is read from its source and rechecked here. - **936 files** the platforms' emulators load are still to be found, and 136 more cannot be sourced at all (per-user keys, user-filled slots, dumps nobody has made). Both are named in the [gap analysis](https://abdess.github.io/retrobios/gaps/) - **12 platforms** supported with platform-specific verification @@ -73,7 +77,7 @@ Each file is checked the way your platform checks it. Most compare a checksum, t - **533 systems** handled by those emulators (NES, SNES, PlayStation, Saturn, Dreamcast, ...) - **19,526 files in the collection**, each with its SHA1, MD5, SHA256, CRC32 and Adler-32 fingerprints: 5,743 system files, 2,851 arcade ROM sets, 10,932 game and engine data files. That is every platform and emulator together, so no pack holds them all: each carries what its own emulators load, counted in the download table - **555 of 5,743 system files** matched to dump-preservation catalogs (No-Intro, Redump, TOSEC). Arcade sets and engine data fall outside what those catalogs index -- **16011 MB** total collection size +- **15.6 GB** for the whole collection ## Supported systems @@ -146,8 +150,7 @@ The [documentation site](https://abdess.github.io/retrobios/) provides: ## How it works -Documentation and metadata can drift from what emulators actually load. -To keep packs accurate, platform lists are checked against emulator source code, file by file where a profile exists. When the two disagree, the code wins. +A platform's BIOS list and an emulator's code are maintained separately. Each list is compared with the emulator source code, file by file where a profile exists, and where the two differ the code decides. Hashes document what emulator code loads and accepts, not dump provenance. That boundary, and how it relates to preservation catalogs such as No-Intro, is drawn in the [FAQ](https://abdess.github.io/retrobios/wiki/faq/#are-these-files-verified-against-original-hardware-dumps). diff --git a/scripts/generate_readme.py b/scripts/generate_readme.py index e0650551..4f4dd4e1 100644 --- a/scripts/generate_readme.py +++ b/scripts/generate_readme.py @@ -329,7 +329,6 @@ def _catalog_matched_line(db: dict) -> list[str]: def generate_readme(db: dict, platforms_dir: str) -> str: total_files = db.get("total_files", 0) total_size = db.get("total_size", 0) - size_mb = total_size / (1024 * 1024) ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") platform_names = list_registered_platforms(platforms_dir, include_archived=True) @@ -397,9 +396,13 @@ def generate_readme(db: dict, platforms_dir: str) -> str: "# SD card mounted on a PC: --dest is the BIOS folder on the card", "# (RetroArch on Switch: retroarch/cores/system, on Android: RetroArch/system)", "curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --platform retroarch --dest /path/to/sdcard/retroarch/cores/system", + "", + "# Options in PowerShell: anything after | iex goes to iex, so the script runs as a block", + "&([scriptblock]::Create((irm https://raw.githubusercontent.com/Abdess/retrobios/main/install.ps1))) --check", "```", "", "The script auto-detects your platform, downloads only missing files, and verifies checksums.", + f"Every option, and what the installer detects and writes, is on the [installer page]({SITE_URL}wiki/installer/#passing-options).", "", "## Download BIOS packs", "", @@ -462,16 +465,17 @@ def generate_readme(db: dict, platforms_dir: str) -> str: "", "Each file is checked the way your platform checks it. Most compare" " a checksum, the fingerprint of a file's contents, which catches a" - " corrupt or unexpected copy. RetroArch, Lakka and RetroPie only" - " look for the filename, because that is all their code does: the" + " corrupt or unexpected copy. RetroArch, Lakka and RetroPie check" + " that the file is present under its name without reading its" + " contents (`path_is_valid` in RetroArch's `core_info.c`): the" " Coverage table says which applies to you. Independently of that," " the collection records five fingerprints per file, and wherever" " an emulator's code states an expected size or hash, that value is" " read from its source and rechecked here.", "", ( - f"- **{acquirable_total} files** the platforms' emulators load" - f" are still to be found, and {unsourceable_total} more cannot" + f"- **{acquirable_total:,} files** the platforms' emulators load" + f" are still to be found, and {unsourceable_total:,} more cannot" f" be sourced at all (per-user keys, user-filled slots, dumps" f" nobody has made). Both are named in the" f" [gap analysis]({SITE_URL}gaps/)" @@ -484,7 +488,7 @@ def generate_readme(db: dict, platforms_dir: str) -> str: f"- **{len(system_ids)} systems** handled by those emulators (NES, SNES, PlayStation, Saturn, Dreamcast, ...)", collection_line(total_files, comp), *_catalog_matched_line(db), - f"- **{size_mb:.0f} MB** total collection size", + f"- **{format_size(total_size)}** for the whole collection", "", "## Supported systems", "", @@ -621,10 +625,10 @@ def generate_readme(db: dict, platforms_dir: str) -> str: "", "## How it works", "", - "Documentation and metadata can drift from what emulators actually load.", - "To keep packs accurate, platform lists are checked against emulator" - " source code, file by file where a profile exists. When the two" - " disagree, the code wins.", + "A platform's BIOS list and an emulator's code are maintained" + " separately. Each list is compared with the emulator source code," + " file by file where a profile exists, and where the two differ the" + " code decides.", "", "Hashes document what emulator code loads and accepts, not dump" " provenance. That boundary, and how it relates to preservation" diff --git a/scripts/generate_site.py b/scripts/generate_site.py index 0bad09ca..41de18f5 100644 --- a/scripts/generate_site.py +++ b/scripts/generate_site.py @@ -2697,7 +2697,7 @@ def generate_emulators_index(profiles: dict) -> str: lines = [ "# Emulators", "", - f"**{len(unique)}** emulator profiles, **{total_files}** files total, **{len(aliases)}** aliases.", + f"**{len(unique):,}** emulator profiles, **{total_files:,}** files total, **{len(aliases):,}** aliases.", "", "| Classification | Count | Description |", "|---------------|-------|-------------|", diff --git a/tests/test_doc_pages.py b/tests/test_doc_pages.py index 4b95dec7..ff40b6cb 100644 --- a/tests/test_doc_pages.py +++ b/tests/test_doc_pages.py @@ -274,6 +274,7 @@ class PeerToneTowardPlatforms(unittest.TestCase): r"(?i)\bgets wrong\b|\bstale (hash|entries|entry)\b||\bpatch their\b" r"|, corrected\b|\bcorrected in place\b|\bdeclare incorrectly\b|\blist error\b" r"|\btheir syntax\b|\bthe platform lacks\b|\bthe odd one\b|\bmay not match reality\b" + r"|\ball their code does\b|\bcan drift from\b" ) def test_published_pages(self): @@ -628,5 +629,44 @@ class ScratchFilesGoToRepoTmp(unittest.TestCase): self.assertIn("tmp/", (ROOT / ".gitignore").read_text(encoding="utf-8").splitlines()) +class ReadmeInstallerOptions(unittest.TestCase): + """The README named --system, --region and --check but showed options + only after `sh -s --`. Appended to `irm ... | iex`, PowerShell rejects + them, and the form that works was on the installer page alone, which the + README never linked.""" + + def test_quick_install_gives_the_powershell_form_and_the_page(self): + import generate_readme + + source = inspect.getsource(generate_readme.generate_readme) + self.assertIn("&([scriptblock]::Create((irm https://raw.githubusercontent.com/Abdess/retrobios/main/install.ps1)))", source) + self.assertIn("wiki/installer/#passing-options", source) + self.assertIn("## Passing options", _page("installer.md")) + readme = (ROOT / "README.md").read_text(encoding="utf-8") + quick = _section(readme, "Quick install") + self.assertIn("[scriptblock]::Create", quick) + self.assertIn("wiki/installer/#passing-options", quick) + self.assertNotRegex(readme, r"(?m)^irm \S+ \| iex \S") + + +class PublishedNumbersShareOneFormat(unittest.TestCase): + """The README gave the collection as `16011 MB` beside `19,526 files`, + the site home as 15.6 GB, and the emulators page `10095 files`.""" + + def test_generators_format_counts_and_sizes_alike(self): + import generate_readme + import generate_site + + readme_source = inspect.getsource(generate_readme.generate_readme) + self.assertNotIn("size_mb", readme_source) + self.assertIn("format_size(total_size)", readme_source) + self.assertIn("{total_files:,}", inspect.getsource(generate_site)) + self.assertEqual(generate_readme.format_size(16011 * 1024 * 1024), "15.6 GB") + + def test_the_readme_has_no_bare_large_count(self): + readme = (ROOT / "README.md").read_text(encoding="utf-8") + self.assertEqual(re.findall(r"\*\*\d{4,}\b[^*]*\*\*", readme), []) + + if __name__ == "__main__": unittest.main()