diff --git a/install.ps1 b/install.ps1 index 365f4af6..be417686 100644 --- a/install.ps1 +++ b/install.ps1 @@ -11,7 +11,7 @@ $ErrorActionPreference = "Stop" $defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" - $defaultInstallSha256 = "441fc1f7887aff7808b7b41182fdb18868ce36a50a2bbbba9bb81e595cb3b732" + $defaultInstallSha256 = "d32af09905abef095c8e5e8fa832fbc76d1556e9cd099b81227d68d1d66d2915" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index 6401e56e..48164438 100644 --- a/install.py +++ b/install.py @@ -569,8 +569,14 @@ def _os_name() -> str: def _emit_check( plat: str, manifest: dict, bios_path: Path, files: list[dict], up_to_date: list[dict], mismatched: list[dict], data_missing: int, not_installable: int, + chosen: list[str] | None = None, ) -> None: - """One event per file, per system and per platform after a check.""" + """One event per file, per system and per platform after a check. + + With systems chosen, only those are described: a file of SkyEmu's + carries four systems, and --system nintendo-gba described gb, gbc and + ds by the few files the choice kept of them. + """ present = {id(entry) for entry in up_to_date} wrong = {id(entry) for entry in mismatched} systems: dict[str, dict[str, int]] = {} @@ -591,6 +597,8 @@ def _emit_check( counts["bytes_needed"] += size names = manifest.get("system_names") or {} for system in sorted(systems): + if chosen and system not in chosen: + continue EVENTS.emit("system", platform=plat, system=system, name=", ".join(names.get(system) or [system]), **systems[system]) needed = [entry for entry in files if id(entry) not in present] @@ -7832,6 +7840,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: _emit_check( plat_name, manifest, bios_path, files, up_to_date, mismatched, sum(len(state[1]) for _entry, state in data_states), len(omitted_files), + chosen=selection[0] if selection else None, ) total_verified += len(up_to_date) diff --git a/install.sh b/install.sh index bc701f70..b638b333 100755 --- a/install.sh +++ b/install.sh @@ -18,7 +18,7 @@ esac TEMP_INSTALLER="" TEMP_DIRECTORY="" DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" -DEFAULT_INSTALL_SHA256="441fc1f7887aff7808b7b41182fdb18868ce36a50a2bbbba9bb81e595cb3b732" +DEFAULT_INSTALL_SHA256="d32af09905abef095c8e5e8fa832fbc76d1556e9cd099b81227d68d1d66d2915" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/tests/test_install.py b/tests/test_install.py index e0bca74c..27129751 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -4994,6 +4994,31 @@ def _events(proc: subprocess.CompletedProcess) -> list[dict]: return [json.loads(line) for line in proc.stdout.splitlines()] +class SystemEventsFollowTheChoice(unittest.TestCase): + """--system nintendo-gba wrote `system` events for nintendo-ds, gb and + gbc: SkyEmu's files carry four systems, and each was described by the + few of its files the choice kept.""" + + def test_only_the_chosen_systems_are_described(self): + files = [{"dest": "gba_bios.bin", "size": 1, "systems": ["nintendo-gba"]}, + {"dest": "SkyEmu/dmg.bin", "size": 1, + "systems": ["nintendo-gb", "nintendo-gba"]}] + stream = io.StringIO() + install.EVENTS.open(stream) + self.addCleanup(setattr, install.EVENTS, "stream", None) + install._emit_check("retroarch", {}, Path("/b"), files, [], [], 0, 0, + chosen=["nintendo-gba"]) + systems = [json.loads(line)["system"] for line in stream.getvalue().splitlines() + if json.loads(line)["event"] == "system"] + self.assertEqual(systems, ["nintendo-gba"]) + stream.seek(0) + stream.truncate() + install._emit_check("retroarch", {}, Path("/b"), files, [], [], 0, 0) + systems = [json.loads(line)["system"] for line in stream.getvalue().splitlines() + if json.loads(line)["event"] == "system"] + self.assertEqual(systems, ["nintendo-gb", "nintendo-gba"]) + + class EventsDescribeTheRun(unittest.TestCase, _SyntheticTree): """--events: the handheld port reads the run as JSON lines on stdout and never parses the text, which goes to stderr.""" diff --git a/wiki/installer.md b/wiki/installer.md index 6934869f..daf32cc5 100644 --- a/wiki/installer.md +++ b/wiki/installer.md @@ -505,7 +505,7 @@ what the options name, everything by default. | `--emulator NAMES` | Install what these emulators read on the detected platform, and nothing else: their own files and the platform's files of the systems they run. Each emulator page on the site gives this command. `--list-emulators` prints the names, buildbot names such as `mednafen_psx` included | | `--region LIST` | Preferred regions, best first (`us,eu,jp`): keep one BIOS per region where a system has several. Accepts the names and aliases of `generate_pack.py --region` | | `--no-game-data` | Leave out game data (a game's own files, not firmware) and install the firmware only. What it leaves out is named. See [Firmware without game data](#firmware-without-game-data) | -| `--list-systems` | Print a platform's systems with the files and size each holds | +| `--list-systems` | Print a platform's systems with the files and size each holds, the files other systems share too counted apart | | `--list-cores` | Print the cores whose extra files a platform installs | | `--list-emulators` | Print every name `--emulator` accepts, each buildbot name beside the emulator it stands for | | `--romm-firmware TEMPLATE` | RomM: where each platform's firmware goes in the library, as `filesystem.structure.firmware` in RomM's `config.yml` says (`{platform}/bios` for a library laid out as `{platform}/roms`). Read from `config.yml` beside the library when it is there. See [RomM firmware layout](#romm-firmware-layout) | @@ -1047,7 +1047,7 @@ kind, and each kind has exactly the keys below, in this order. The schema is | `detect` | `os`, `os_name`, `platforms` | Once the platforms are known. `os_name` comes from `/etc/os-release`. `platforms` lists `{platform, name, bios_dir}`, and is empty when nothing supported was found | | `error` | `stage`, `reason`, `platform`, `message` | The file list could not be read (`stage` is `manifest`). `reason` is `network`, `not_found` or `invalid`, `clock` when the server's certificate was refused and the system clock reads a date before the installer was written, or `no_ca` when the machine holds no list of trusted certificates (`SSL_CERT_FILE` names one). `message` says it in words | | `file` | `platform`, `dest`, `systems`, `size`, `state` | Each file of the list after the check. `state` is `present` (hash verified), `wrong_hash` or `missing` | -| `system` | `platform`, `system`, `name`, `files`, `present`, `missing`, `wrong_hash`, `bytes_needed` | Each system, sorted by id. Files with no system count under `other`. `name` is the platform's own name for it | +| `system` | `platform`, `system`, `name`, `files`, `present`, `missing`, `wrong_hash`, `bytes_needed` | Each system, sorted by id, and with `--system` only the systems named. Files with no system count under `other`. `name` is the platform's own name for it | | `check` | `platform`, `name`, `bios_dir`, `files`, `present`, `missing`, `wrong_hash`, `bytes_needed`, `data_missing`, `not_installable` | The platform's totals. `data_missing` counts data-tree files to fetch, `not_installable` the files the collection cannot supply | | `download` | `platform`, `files`, `bytes` | Before the downloads start | | `progress` | `files_done`, `files_total`, `bytes_done`, `bytes_total` | At most every half second while bytes arrive |