diff --git a/install.ps1 b/install.ps1 index 93fff7d90..00d2dc7d4 100644 --- a/install.ps1 +++ b/install.ps1 @@ -16,7 +16,7 @@ # and Invoke-WebRequest throws on a cut transfer before the hash is read: # the site's build rewrites this line there (scripts/sitebootstrap.py). $mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." - $defaultInstallSha256 = "e1460704fe40e4c91b9c410ae119ceb1ece3b375d9a3dc6be00a96d5f5d348bf" + $defaultInstallSha256 = "000880ee7a1293a5a3bc868b6bf7f3a4f262b61c485564cc11b433908acca817" # The pin above refuses any changed byte: this cap only stops a body that # cannot be the installer (a sign-in portal's page) before it is hashed. $maximumInstallerBytes = 8MB diff --git a/install.py b/install.py index 873ac0fa7..f01e2d8cc 100644 --- a/install.py +++ b/install.py @@ -6548,10 +6548,6 @@ def apply_record(args: argparse.Namespace, plat: str, folder: Path) -> dict | No return setup -# Windows marks a directory junction, and any other reparse point, with this -# attribute. Before Python 3.12 lstat does not report a junction as a link, -# and os.walk(followlinks=False) descends into it. -_REPARSE_POINT = getattr(stat, "FILE_ATTRIBUTE_REPARSE_POINT", 0x400) def _is_link(info: os.stat_result) -> bool: @@ -13878,6 +13874,8 @@ APPLE_DOUBLE = "._" # Folders the kernel makes up on the fly: endless, and never a copy. PSEUDO_FOLDERS = frozenset() if os.name == "nt" else frozenset(("/proc", "/sys", "/dev")) # FILE_ATTRIBUTE_REPARSE_POINT: a junction, a mount point or a link on Windows. +# Before Python 3.12 lstat does not report a junction as a link, and +# os.walk(followlinks=False) descends into it. _REPARSE_POINT = getattr(stat, "FILE_ATTRIBUTE_REPARSE_POINT", 0x400) # Errors a member of someone's ZIP can raise on reading: damaged, encrypted # (RuntimeError), or packed with a method zipfile lacks. diff --git a/install.sh b/install.sh index 47dcfa96b..0f89cf441 100755 --- a/install.sh +++ b/install.sh @@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins # curl or wget stop on a cut transfer before the hash is read: the site's # build rewrites this line there (scripts/sitebootstrap.py). MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." -DEFAULT_INSTALL_SHA256="e1460704fe40e4c91b9c410ae119ceb1ece3b375d9a3dc6be00a96d5f5d348bf" +DEFAULT_INSTALL_SHA256="000880ee7a1293a5a3bc868b6bf7f3a4f262b61c485564cc11b433908acca817" # The pin above refuses any changed byte: this cap only stops a body that # cannot be the installer (a sign-in portal's page) before it is hashed. MAX_INSTALLER_BYTES=8388608 diff --git a/install/launchers/index.json b/install/launchers/index.json index 583697cdb..570c033de 100644 --- a/install/launchers/index.json +++ b/install/launchers/index.json @@ -27,8 +27,8 @@ { "dest": "roms/ports/retrobios/install.py", "repo_path": "install.py", - "size": 1285922, - "sha256": "e1460704fe40e4c91b9c410ae119ceb1ece3b375d9a3dc6be00a96d5f5d348bf", + "size": 1285764, + "sha256": "000880ee7a1293a5a3bc868b6bf7f3a4f262b61c485564cc11b433908acca817", "executable": false }, { @@ -71,8 +71,8 @@ "muos": { "archive": { "dest": "ARCHIVE/RetroBIOS.muxapp", - "size": 1339547, - "sha256": "974a225380c719ecee6dbc226ed17d1709ed406d08556657c15cccebb1eb587c" + "size": 1339389, + "sha256": "e305f03c65adbf3cf4eab08eaad2091bc52afa397c81895679d6172ca12ba061" }, "members": [ { @@ -92,8 +92,8 @@ { "name": "RetroBIOS/install.py", "repo_path": "install.py", - "size": 1285922, - "sha256": "e1460704fe40e4c91b9c410ae119ceb1ece3b375d9a3dc6be00a96d5f5d348bf", + "size": 1285764, + "sha256": "000880ee7a1293a5a3bc868b6bf7f3a4f262b61c485564cc11b433908acca817", "executable": false }, { @@ -166,8 +166,8 @@ { "dest": ".config/modules/retrobios/install.py", "repo_path": "install.py", - "size": 1285922, - "sha256": "e1460704fe40e4c91b9c410ae119ceb1ece3b375d9a3dc6be00a96d5f5d348bf", + "size": 1285764, + "sha256": "000880ee7a1293a5a3bc868b6bf7f3a4f262b61c485564cc11b433908acca817", "executable": false }, { diff --git a/mypy-baseline.txt b/mypy-baseline.txt index 4814cbb7d..f7b159c43 100644 --- a/mypy-baseline.txt +++ b/mypy-baseline.txt @@ -8,8 +8,6 @@ install.py:0: error: "object" has no attribute "get" [attr-defined] install.py:0: error: "object" has no attribute "get" [attr-defined] install.py:0: error: "object" object is not iterable [misc] install.py:0: error: "object" object is not iterable [misc] -install.py:0: error: "str" has no attribute "append" [attr-defined] -install.py:0: error: "str" has no attribute "append" [attr-defined] install.py:0: error: Argument 1 to "_ZippedLookup" has incompatible type "Optional[FolderIndex]"; expected "FolderIndex" [arg-type] install.py:0: error: Argument 1 to "__iadd__" of "list" has incompatible type "Invocation"; expected "Iterable[str]" [arg-type] install.py:0: error: Argument 1 to "_digest_file" has incompatible type "Optional[Path]"; expected "Path" [arg-type] @@ -118,7 +116,6 @@ install.py:0: error: Incompatible types in assignment (expression has type "int" install.py:0: error: Incompatible types in assignment (expression has type "int", variable has type "str") [assignment] install.py:0: error: Incompatible types in assignment (expression has type "list[dict[Any, Any]]", variable has type "int") [assignment] install.py:0: error: Incompatible types in assignment (expression has type "list[str]", variable has type "Invocation") [assignment] -install.py:0: error: Incompatible types in assignment (expression has type "list[str]", variable has type "str") [assignment] install.py:0: error: Incompatible types in assignment (expression has type "set[int]", variable has type "int") [assignment] install.py:0: error: Incompatible types in assignment (expression has type "set[int]", variable has type "list[dict[Any, Any]]") [assignment] install.py:0: error: Incompatible types in assignment (expression has type "set[int]", variable has type "list[dict[Any, Any]]") [assignment] diff --git a/scripts/sitediagrams.py b/scripts/sitediagrams.py index 09e78ddfd..c62fd7017 100644 --- a/scripts/sitediagrams.py +++ b/scripts/sitediagrams.py @@ -904,7 +904,9 @@ GLANCE_GROUPS: tuple[tuple[str, tuple[str, ...]], ...] = ( "--cores-dir")), ("Look first", ("--check", "--dry-run", "--list-platforms", "--list-targets", "--list-systems", "--list-cores", "--list-emulators")), - ("From files on hand", ("--from", "--from-pack", "--manifest", "--offline", "--restore")), + ("From files on hand", ("--from", "--from-pack", "--manifest", "--offline")), + ("Remove and put back", ("--remove", "--file", "--backup", "--backups", "--restore", + "--delete-backup")), ("How the run talks", ("--tui", "--plain", "--no-input", "--yes", "--quiet", "--verbose", "--events", "--jobs", "--version", "--help")), ) diff --git a/wiki/testing-guide.md b/wiki/testing-guide.md index 2c1f6a867..a31eb1127 100644 --- a/wiki/testing-guide.md +++ b/wiki/testing-guide.md @@ -59,7 +59,7 @@ Every module in `tests/`, by the area it guards. | Packs and manifests | synthetic + real packs | `test_artifact_lock`, `test_atomic_artifacts`, `test_batocera_cores`, `test_core_data_trees`, `test_deterministic_zip`, `test_emulator_pack_counts`, `test_finalize_pack_names`, `test_large_file_cache`, `test_libretro_layout`, `test_manifest_entry`, `test_minui_platform`, `test_no_game_data`, `test_pack_conformance_dirs`, `test_pack_core_extras`, `test_pack_counts`, `test_pack_destinations`, `test_pack_failures`, `test_pack_file_names`, `test_pack_grouping`, `test_pack_integrity`, `test_pack_member_identity`, `test_pack_readme`, `test_platform_inheritance`, `test_platform_keys`, `test_release_packs`, `test_required_only_archives`, `test_required_only_twins`, `test_save_root`, `test_split_extras`, `test_split_names`, `test_split_pack`, `test_system_pack_extras`, `test_system_pack_parity`, `test_torrentzip`, `test_which_pack` | | Slots and regions | synthetic + profiles | `test_region`, `test_region_agnostic_scan`, `test_region_groups`, `test_region_held`, `test_region_platform_index`, `test_region_required_only`, `test_slot`, `test_slots`, `test_slots_shipped_file` | | Hardware targets and systems | synthetic + target files | `test_amberelec_targets`, `test_emuelec_targets`, `test_extract_targets`, `test_lakka_targets`, `test_libretro_slugs`, `test_system_ids`, `test_system_selection`, `test_target_names`, `test_target_scrapers`, `test_target_systems`, `test_target_verify` | -| Installer and downloads | loopback server | `test_check_release`, `test_download`, `test_install`, `test_install_cores`, `test_install_experience`, `test_install_filesystems`, `test_install_app`, `test_install_from`, `test_install_games`, `test_install_journeys`, `test_install_offline`, `test_install_selection`, `test_install_tui`, `test_pypi_package` | +| Installer and downloads | loopback server | `test_check_release`, `test_download`, `test_install`, `test_install_cores`, `test_install_experience`, `test_install_filesystems`, `test_install_app`, `test_install_from`, `test_install_games`, `test_install_journeys`, `test_install_offline`, `test_install_removal`, `test_install_selection`, `test_install_tui`, `test_pypi_package` | | Handheld launchers | a pty as the console, fake installer and firmware tools, stubbed PortMaster dialogs | `test_handheld_launchers`, `test_port` | | Running cores | parsers on fixed inputs, a libretro core built from C in the test when a compiler exists | `test_core_probe` | | Measurement records | synthetic record files, the committed `measurements/` against HEAD, the **Proof** line naming the BIOS a core ran, and that no page shows a Tested block, a region outcome or a time per frame | `test_measurements` |