diff --git a/install.ps1 b/install.ps1 index 013467a5..2ab5bf18 100644 --- a/install.ps1 +++ b/install.ps1 @@ -11,7 +11,7 @@ $ErrorActionPreference = "Stop" $defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" - $defaultInstallSha256 = "568d9399c5639db607cfc3944fa46a0dfa8d47741291d9346ed336cd2500eb00" + $defaultInstallSha256 = "851c1d9e8b2b481adf50d1af2c67d1e44d9b50504fdef3d5b6514332ac4457eb" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index bc0b9076..74807803 100644 --- a/install.py +++ b/install.py @@ -6394,6 +6394,12 @@ def _found_elsewhere( ) -> tuple[str, str]: """(reason, folder too deep) for an entry missing at its place.""" dest = str(entry.get("dest", "")) + if entry.get("case_variant"): + # A pack is read on Windows and macOS too, where two names that + # differ only by case are one file: it carries one of the pair. Moving + # the other copy here would take it from the core that opens it. + return ("a second name the pack leaves out: Windows and macOS see it " + "as the same file. Run the command without --check to add it"), "" name = dest.rsplit("/", 1)[-1] sizes = {copy.get("size") for copy in _copies(entry) if isinstance(copy.get("size"), int)} sha1s = {copy.get("sha1") for copy in _copies(entry) if copy.get("sha1")} @@ -7294,7 +7300,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: if variants and case_kept: # The list is folded for Windows and macOS, but here bios.col and # BIOS.col are two files that two cores open. - files = files + variants + files = files + [{**variant, "case_variant": True} for variant in variants] if not case_kept: files, folded = fold_case_twins(files) if folded: diff --git a/install.sh b/install.sh index 999f63c0..b3217604 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="568d9399c5639db607cfc3944fa46a0dfa8d47741291d9346ed336cd2500eb00" +DEFAULT_INSTALL_SHA256="851c1d9e8b2b481adf50d1af2c67d1e44d9b50504fdef3d5b6514332ac4457eb" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/tests/test_install_offline.py b/tests/test_install_offline.py index ad555075..834e320a 100644 --- a/tests/test_install_offline.py +++ b/tests/test_install_offline.py @@ -168,6 +168,23 @@ class CheckNamesWhyAFileIsRefused(Scratch): self.place("GBA_BIOS.BIN", GBA) self.assertIn("case of the name: the folder holds GBA_BIOS.BIN", self.check()) + def test_a_case_twin_the_pack_leaves_out_is_not_a_wrong_folder(self): + """np2kai/2608_bd.wav and np2/2608_bd.wav hold the same bytes. Told + "wrong folder", a user moved np2's copy and broke that core.""" + probe = self.root / "CaseProbe" + probe.write_text("x") + if (self.root / "caseprobe").exists(): + self.skipTest("this filesystem does not keep case") + data = json.loads(self.list.read_text()) + twin = next(f for f in data["files"] if f["dest"] == "gba_bios.bin") + data["case_variants"] = [{**twin, "dest": "twin/gba_bios.bin"}] + self.list.write_text(json.dumps(data)) + self.complete() + out = self.check() + self.assertIn("missing: twin/gba_bios.bin", out) + self.assertIn("a second name the pack leaves out", out) + self.assertNotIn("wrong folder: it is at gba_bios.bin", out) + def test_a_nested_bios_folder_is_named(self): for name, data in PAYLOAD.items(): self.place(f"system/{name}", data)