chore: merge the platform quirks branch

# Conflicts:
#	install.ps1
#	install.sh
#	install/launchers/index.json
#	wiki/testing-guide.md
This commit is contained in:
Abdessamad Derraz committed 2026-11-09 20:56:04 +01:00
commit 20291e3573
15 files changed
+360 -19

No files matched your search

+18 -1
View File
@@ -416,6 +416,17 @@ def platform_list_version(config: dict, platform: str) -> str:
PACK_DOCUMENTS = ("README.txt", "manifest.json")
def pack_markers(
platform_name: str, target_name: str | None, platforms_dir: str
) -> tuple[str, ...]:
"""The empty files a pack carries for the systems it is unzipped on,
as named before flattening: the .nomedia of a pack for Android."""
from common import list_available_targets
names = [t["name"] for t in list_available_targets(platform_name, platforms_dir)]
return (MEDIA_MARKER,) if lands_on_android(names, target_name) else ()
def core_data_trees(
config: dict,
profiles: dict[str, dict],
@@ -1477,6 +1488,10 @@ def generate_pack(
),
)
_write_generated_member(zf, "README.txt", readme_text)
for marker in pack_markers(platform_name, target_name, platforms_dir):
_write_generated_member(
zf, _flat(f"{base_dest}/{marker}" if base_dest else marker, base_dest, flatten), ""
)
_report_pack_counts(
zip_path, file_status, total_files, core_count, source,
@@ -5147,7 +5162,7 @@ def generate_manifest(
"total_size": total_size,
"pack_files": (
len(manifest_files) + len(data_sizes) + len(PACK_DOCUMENTS)
+ len(rename_notes)
+ len(rename_notes) + len(pack_markers(platform_name, target_name, platforms_dir))
),
"pack_size": total_size + sum(data_sizes),
"total_omitted": len(omitted_by_destination),
@@ -5719,6 +5734,8 @@ def verify_and_finalize_packs(
return all_ok
from packpaths import ( # noqa: E402,F401
MEDIA_MARKER,
lands_on_android,
_archive_destination,
_path_parents,
_has_path_conflict,
+17
View File
@@ -192,6 +192,23 @@ def _register_path(dest: str, seen_files: set[str], seen_parents: set[str]) -> N
for parent in _path_parents(dest):
seen_parents.add(parent)
# Android's media scanner hides a folder holding a .nomedia file, and every
# folder below it (MediaProvider a183e2b9, FileUtils.java:1587-1629
# isDirectoryHidden, ModernMediaScanner.java:845-846). RetroArch writes none
# (libretro-common/file/file_path_io.c:194 only skips one), so a pack
# unzipped into RetroArch Android's system folder put its samples, overlays
# and videos in the gallery and music apps.
MEDIA_MARKER = ".nomedia"
def lands_on_android(target_names: Iterable[str], target: str | None) -> bool:
"""Whether a pack can be unzipped on Android: its target is an Android
one, or, unfiltered, the platform files one."""
if target:
return target.startswith("android")
return any(name.startswith("android") for name in target_names)
def _flat(arcname: str, prefix: str, flatten: bool) -> str:
"""Strip base_destination prefix from ZIP arcname when flattening."""
if flatten and prefix and arcname.startswith(prefix + "/"):
+4 -4
View File
@@ -10,7 +10,7 @@ from collections import Counter
from auto_fetch import DEFAULT_BIOS_DIR
from artifacts import _build_timestamp
from packpaths import _has_path_conflict
from packpaths import MEDIA_MARKER, _has_path_conflict
from ziptools import build_zip_contents_index
from ziptools import check_inside_zip
from nativemode import digest_algorithm
@@ -170,7 +170,7 @@ def verify_pack(
# (bios/INSTRUCTIONS_x.txt, games/keen6/INSTRUCTIONS_y.txt), so
# they are told by their own name, not by a root prefix.
base = name.rsplit("/", 1)[-1]
if base.startswith(("INSTRUCTIONS_", "RENAMED_")) or name in (
if base.startswith(("INSTRUCTIONS_", "RENAMED_")) or base == MEDIA_MARKER or name in (
"manifest.json",
"README.txt",
):
@@ -539,7 +539,7 @@ def _structural_errors(zf: zipfile.ZipFile, zip_set: set) -> list[str]:
if "GraphicMods" not in info.filename and info.filename not in (
"manifest.json",
"README.txt",
):
) and info.filename.rsplit("/", 1)[-1] != MEDIA_MARKER:
errors.append(f"zero-byte: {info.filename}")
return errors
@@ -746,7 +746,7 @@ def verify_pack_against_platform(
is_flat = bool(base_dest) and not any(
n.startswith(base_dest + "/")
for n in zip_set
if n not in ("README.txt", "manifest.json") and not n.endswith("/")
if n not in ("README.txt", "manifest.json", MEDIA_MARKER) and not n.endswith("/")
)
errors.extend(_structural_errors(zf, zip_set))