mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-18 09:23:26 -05:00
fix: keep one case twin where case folds
This commit is contained in:
1 parent
14f78ab634
commit
8f7b8c9dc9
5 files changed
+58
-4
No files matched your search
+1
-1
@@ -8,7 +8,7 @@ param(
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
$defaultInstallSha256 = "b163e90cc3101ce499e1f01899a398fbea27656054fb2fb9b31f07631d15f19a"
|
||||
$defaultInstallSha256 = "133242b850a1e2dfa820f39b466c8b56a9363aee1cc8df1e9a1f9f28744a0cdc"
|
||||
$maximumInstallerBytes = 2MB
|
||||
$installerExit = 0
|
||||
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
||||
|
||||
+31
-1
@@ -1134,6 +1134,24 @@ def keeps_case(directory: Path) -> bool:
|
||||
os.unlink(name)
|
||||
|
||||
|
||||
def fold_case_twins(files: list[dict]) -> tuple[list[dict], list[str]]:
|
||||
"""One file per name where the directory folds case; the others named.
|
||||
|
||||
The first in manifest order stays, as the pack's own order places it.
|
||||
"""
|
||||
kept: list[dict] = []
|
||||
seen: set[str] = set()
|
||||
folded: list[str] = []
|
||||
for entry in files:
|
||||
key = str(entry.get("dest", "")).casefold()
|
||||
if key in seen:
|
||||
folded.append(str(entry.get("dest", "")))
|
||||
continue
|
||||
seen.add(key)
|
||||
kept.append(entry)
|
||||
return kept, folded
|
||||
|
||||
|
||||
def installed_cores(dirs: list[Path]) -> list[str]:
|
||||
"""The cores present in these directories, by the name the buildbot uses.
|
||||
|
||||
@@ -3218,10 +3236,22 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None:
|
||||
files = manifest.get("files", [])
|
||||
omitted_files = manifest.get("omitted_files", [])
|
||||
variants = manifest.get("case_variants", [])
|
||||
if variants and keeps_case(bios_path):
|
||||
case_kept = keeps_case(bios_path)
|
||||
if variants and case_kept:
|
||||
# The list is folded for Windows and macOS; here bios.col and
|
||||
# BIOS.col are two files that two cores open.
|
||||
files = files + variants
|
||||
if not case_kept:
|
||||
files, folded = fold_case_twins(files)
|
||||
if folded:
|
||||
# Batocera's share opened over SMB, an exFAT card: the second
|
||||
# spelling overwrote the first, and every --check found one
|
||||
# of them wrong and fetched it again.
|
||||
shown = ", ".join(folded[:3]) + (" ..." if len(folded) > 3 else "")
|
||||
print(
|
||||
f" {_plural(len(folded), 'file')} left out: {bios_path} does not keep "
|
||||
f"case and holds another file under the same name ({shown})"
|
||||
)
|
||||
|
||||
if args.list_targets:
|
||||
targets = fetch_targets(plat_name)
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ esac
|
||||
TEMP_INSTALLER=""
|
||||
TEMP_DIRECTORY=""
|
||||
DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
DEFAULT_INSTALL_SHA256="b163e90cc3101ce499e1f01899a398fbea27656054fb2fb9b31f07631d15f19a"
|
||||
DEFAULT_INSTALL_SHA256="133242b850a1e2dfa820f39b466c8b56a9363aee1cc8df1e9a1f9f28744a0cdc"
|
||||
MAX_INSTALLER_BYTES=2097152
|
||||
|
||||
cleanup() {
|
||||
|
||||
+18
-1
@@ -2245,7 +2245,7 @@ class CaseVariants(unittest.TestCase):
|
||||
compact = " ".join(source.split())
|
||||
self.assertIn(
|
||||
'variants = manifest.get("case_variants", []) '
|
||||
"if variants and keeps_case(bios_path):", compact,
|
||||
"case_kept = keeps_case(bios_path) if variants and case_kept:", compact,
|
||||
)
|
||||
|
||||
def test_the_published_retroarch_list_carries_them(self):
|
||||
@@ -2318,5 +2318,22 @@ class TheBoardTheSystemNamesIsTheTarget(unittest.TestCase):
|
||||
self.assertTrue(targets)
|
||||
|
||||
|
||||
|
||||
class CaseTwinsOnAFoldingVolume(unittest.TestCase):
|
||||
"""Batocera and Recalbox list np2kai/bios.rom and np2kai/BIOS.ROM, other
|
||||
bytes each. Installed to a share opened from Windows or an exFAT card,
|
||||
the second overwrote the first and --check never converged."""
|
||||
|
||||
def test_one_file_per_name_is_kept(self):
|
||||
files = [{"dest": "np2kai/bios.rom"}, {"dest": "np2kai/BIOS.ROM"}, {"dest": "x.bin"}]
|
||||
kept, folded = install.fold_case_twins(files)
|
||||
self.assertEqual([f["dest"] for f in kept], ["np2kai/bios.rom", "x.bin"])
|
||||
self.assertEqual(folded, ["np2kai/BIOS.ROM"])
|
||||
|
||||
def test_main_folds_only_where_case_is_not_kept(self):
|
||||
source = " ".join((REPO_ROOT / "install.py").read_text(encoding="utf-8").split())
|
||||
self.assertIn("if not case_kept: files, folded = fold_case_twins(files)", source)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -95,6 +95,13 @@ BIOS directory keeps case and, if it does, also fetches these names. If you
|
||||
extract the ZIP on Linux by hand, take the Lakka pack instead: it is the
|
||||
RetroArch pack with both spellings.
|
||||
|
||||
The reverse happens on Batocera and Recalbox, whose lists hold both spellings
|
||||
because their systems keep case: NP2kai reads `np2kai/bios.rom` and
|
||||
`np2kai/BIOS.ROM` as two different files. Written to a folder that folds case
|
||||
(the share opened from Windows, an exFAT card), one overwrites the other. The
|
||||
installer checks the folder first, keeps one file per name there and lists
|
||||
the ones it left out.
|
||||
|
||||
## Hash mismatch / UNTESTED
|
||||
|
||||
`verify.py` reports `UNTESTED` for a file.
|
||||
|
||||
Reference in new issue
Block a user