From 8b8d94e3314a30d770f207c9abeb3f7a0b5358f3 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Wed, 21 Oct 2026 11:10:46 +0200 Subject: [PATCH] fix: name moved repositories by their new name profile_sync --all reported 18 repositories the forge answers under another owner or name. Each pin resolves in the renamed repository, so the URLs change and the pins stay. flycast2021 builds from metallic77/flycast 603814c9 (ROCKNIX package.mk), whose upstream libretro/flycast now answers as libretro/parallel-dc with 4c293f30 still in its master history. --- emulators/2ship.yml | 4 +-- emulators/bnes.yml | 2 +- emulators/clownmdemu.yml | 2 +- emulators/dsda-doom.yml | 2 +- emulators/fbalpha2019.yml | 2 +- emulators/flycast2021.yml | 4 ++- emulators/lzdoom.yml | 2 +- emulators/mame4droid-2024.yml | 2 +- emulators/mu.yml | 2 +- emulators/pocketcdg.yml | 2 +- emulators/puzzlescript.yml | 2 +- emulators/reicast.yml | 4 +-- emulators/theforceengine.yml | 4 +-- emulators/thepowdertoy.yml | 2 +- emulators/vitavoyager.yml | 2 +- emulators/wolf4sdl.yml | 4 +-- tests/test_profile_repositories.py | 55 ++++++++++++++++++++++++++++++ wiki/testing-guide.md | 2 +- 18 files changed, 78 insertions(+), 21 deletions(-) create mode 100644 tests/test_profile_repositories.py diff --git a/emulators/2ship.yml b/emulators/2ship.yml index 89bb7c6c..8b8c6e53 100644 --- a/emulators/2ship.yml +++ b/emulators/2ship.yml @@ -1,8 +1,8 @@ emulator: 2 Ship 2 Harkinian type: standalone core_classification: game_engine -source: "https://github.com/HarbourMasters/2ship2harkinian" -upstream: "https://github.com/HarbourMasters/2ship2harkinian" +source: "https://github.com/2ship2harkinian/2ship2harkinian" +upstream: "https://github.com/2ship2harkinian/2ship2harkinian" source_commit: "8a24047fbce8915993804e7819f4df4fa591551f" profiled_date: "2026-10-20" core_version: "5.0.1" diff --git a/emulators/bnes.yml b/emulators/bnes.yml index b0bce76d..1dc180c5 100644 --- a/emulators/bnes.yml +++ b/emulators/bnes.yml @@ -2,7 +2,7 @@ emulator: bnes type: libretro core_classification: frozen_snapshot source: "https://github.com/libretro/bnes-libretro" -upstream: "https://github.com/Alcaro/bsnes-gc" +upstream: "https://github.com/Sir-Walrus/bsnes-gc" profiled_date: "2026-03-23" source_commit: "8e26e89a93bef8eb8992d1921b539dce1792660a" core_version: "v083" diff --git a/emulators/clownmdemu.yml b/emulators/clownmdemu.yml index 8655c143..cacf2a6d 100644 --- a/emulators/clownmdemu.yml +++ b/emulators/clownmdemu.yml @@ -2,7 +2,7 @@ emulator: ClownMDEmu type: standalone + libretro core_classification: official_port source: "https://github.com/Clownacy/clownmdemu-libretro" -upstream: "https://github.com/Clownacy/clownmdemu" +upstream: "https://github.com/Clownacy/clownmdemu-core" profiled_date: "2026-03-23" source_commit: "d43c2708b0a31c285ce16724b6c4a2e92af07346" # The core the port vendors at source_commit (common -> core submodule). diff --git a/emulators/dsda-doom.yml b/emulators/dsda-doom.yml index 8bc17594..84732892 100644 --- a/emulators/dsda-doom.yml +++ b/emulators/dsda-doom.yml @@ -1,7 +1,7 @@ emulator: dsda-doom type: standalone core_classification: game_engine -source: "https://github.com/kraflab/dsda-doom" +source: "https://github.com/dsda-org/dsda-doom" profiled_date: "2026-10-20" source_commit: "e443ff7a3e6090a1ff92ad7a426916c4fd35ecc5" core_version: "0.29.4" diff --git a/emulators/fbalpha2019.yml b/emulators/fbalpha2019.yml index b385302e..fc4492a2 100644 --- a/emulators/fbalpha2019.yml +++ b/emulators/fbalpha2019.yml @@ -1,7 +1,7 @@ emulator: "FB Alpha 2019" type: libretro core_classification: frozen_snapshot -source: "https://github.com/libretro/fbalpha" +source: "https://github.com/libretro/beetle-finalarcade2019" upstream: "https://github.com/barry65536/FBAlpha" profiled_date: "2026-10-17" source_commit: "0581797db6fdffd826086b053ced4b6b29bb6678" diff --git a/emulators/flycast2021.yml b/emulators/flycast2021.yml index 925af60c..4567469d 100644 --- a/emulators/flycast2021.yml +++ b/emulators/flycast2021.yml @@ -2,7 +2,7 @@ emulator: "Flycast 2021" type: libretro core_classification: frozen_snapshot source: "https://github.com/metallic77/flycast" -upstream: "https://github.com/libretro/flycast" +upstream: "https://github.com/libretro/parallel-dc" profiled_date: "2026-10-17" source_commit: "603814c9f73b773c455d9a497f389d2f93a257fd" upstream_commit: "4c293f306bc16a265c2d768af5d0cea138426054" @@ -20,6 +20,8 @@ notes: | The libretro/flycast tree as of April 2022 (merge base 4c293f30), from before the libretro fork was rebased on flyinghead's Flycast, with 22 commits by metallic77 on top that tune defaults and build flags for low-end handhelds. + That repository now answers as libretro/parallel-dc, and its master still + descends from 4c293f30. ROCKNIX renames the core option prefix from reicast to flycast2021 and installs the library as flycast2021_libretro.so. ref: core/libretro/libretro.cpp:2296-2300 diff --git a/emulators/lzdoom.yml b/emulators/lzdoom.yml index c38a8635..13ac7907 100644 --- a/emulators/lzdoom.yml +++ b/emulators/lzdoom.yml @@ -1,7 +1,7 @@ emulator: LZDoom type: standalone core_classification: game_engine -source: "https://github.com/drfrag666/gzdoom" +source: "https://github.com/drfrag666/lzdoom" profiled_date: "2026-10-20" source_commit: "4ce19a12164ebd6802b7fb2f94d700a6e736d0fb" core_version: "3.88b" diff --git a/emulators/mame4droid-2024.yml b/emulators/mame4droid-2024.yml index 7bc0a3b9..82e87436 100644 --- a/emulators/mame4droid-2024.yml +++ b/emulators/mame4droid-2024.yml @@ -1,7 +1,7 @@ emulator: MAME4droid 2024 type: standalone core_classification: community_fork -source: "https://github.com/seleuco/MAME4droid-2024" +source: "https://github.com/seleuco/MAME4droid-Current" upstream: "https://github.com/mamedev/mame/tree/mame0289" logo: "https://raw.githubusercontent.com/mamedev/mame/master/docs/source/images/MAMElogo.svg" profiled_date: "2026-08-11" diff --git a/emulators/mu.yml b/emulators/mu.yml index b2f05446..ffb58670 100644 --- a/emulators/mu.yml +++ b/emulators/mu.yml @@ -1,7 +1,7 @@ emulator: Mu type: libretro core_classification: pure_libretro -source: "https://github.com/libretro/Mu" +source: "https://github.com/SquirrelJME/Mu" upstream: "https://github.com/meepingsnesroms/Mu" profiled_date: "2026-03-24" source_commit: "afaeb157b8ba38a4a9bdf426ba663f7efb2cc6f8" diff --git a/emulators/pocketcdg.yml b/emulators/pocketcdg.yml index 5e4d0660..a4e0b297 100644 --- a/emulators/pocketcdg.yml +++ b/emulators/pocketcdg.yml @@ -2,7 +2,7 @@ emulator: PocketCDG type: libretro core_classification: pure_libretro source: "https://github.com/libretro/libretro-pocketcdg" -upstream: "https://github.com/redbug26/libretro-pocketcdg" +upstream: "https://github.com/libretro/libretro-pocketcdg" profiled_date: "2026-03-24" source_commit: "b48b807e770aeea9a9e8f7af36f5e04ed4727aaa" core_version: "Git" diff --git a/emulators/puzzlescript.yml b/emulators/puzzlescript.yml index 31288c33..33d4fae7 100644 --- a/emulators/puzzlescript.yml +++ b/emulators/puzzlescript.yml @@ -1,7 +1,7 @@ emulator: PuzzleScript type: libretro core_classification: game_engine -source: "https://github.com/nwhitehead/pzretro" +source: "https://github.com/amberwhitehead/pzretro" upstream: "https://github.com/increpare/PuzzleScript" profiled_date: "2026-03-25" source_commit: "6d859b47092f585a7ec05804c1d51a1676a06531" diff --git a/emulators/reicast.yml b/emulators/reicast.yml index db6c182e..fa5fc5b8 100644 --- a/emulators/reicast.yml +++ b/emulators/reicast.yml @@ -1,8 +1,8 @@ emulator: Reicast type: standalone core_classification: community_fork -source: "https://github.com/reicast/reicast-emulator" -upstream: "https://github.com/reicast/reicast-emulator" +source: "https://github.com/skmp/reicast-emulator" +upstream: "https://github.com/skmp/reicast-emulator" profiled_date: "2026-10-17" source_commit: "ad61f95dd6b4c6218846a25de6194550311a5d28" pin_frozen: "Recalbox 10.1.1 builds this revision (package/reicast/reicast.mk REICAST_VERSION). Later commits on reicast-emulator are not part of that build." diff --git a/emulators/theforceengine.yml b/emulators/theforceengine.yml index a348eb8a..2b3838da 100644 --- a/emulators/theforceengine.yml +++ b/emulators/theforceengine.yml @@ -1,8 +1,8 @@ emulator: The Force Engine type: standalone core_classification: game_engine -source: "https://github.com/luciusDXL/TheForceEngine" -upstream: "https://github.com/luciusDXL/TheForceEngine" +source: "https://github.com/TheForceEngine/TheForceEngine" +upstream: "https://github.com/TheForceEngine/TheForceEngine" profiled_date: "2026-10-04" source_commit: "cc25205cc94c36a396f6f50295772f6ec83069a2" core_version: "v1.22.420" diff --git a/emulators/thepowdertoy.yml b/emulators/thepowdertoy.yml index 8e749a91..2784f52d 100644 --- a/emulators/thepowdertoy.yml +++ b/emulators/thepowdertoy.yml @@ -2,7 +2,7 @@ emulator: The Powder Toy type: libretro core_classification: pure_libretro source: "https://github.com/libretro/ThePowderToy" -upstream: "https://github.com/ThePowderToy/The-Powder-Toy" +upstream: "https://github.com/The-Powder-Toy/The-Powder-Toy" profiled_date: "2026-03-25" source_commit: "cb3cd4c2e5beddb98b34e6b800fa24e8f96322d9" core_version: "v92.5.336" diff --git a/emulators/vitavoyager.yml b/emulators/vitavoyager.yml index 9ca3204d..b168f3bc 100644 --- a/emulators/vitavoyager.yml +++ b/emulators/vitavoyager.yml @@ -2,7 +2,7 @@ emulator: vitavoyager type: libretro core_classification: community_fork source: "https://github.com/libretro/vitavoyager" -upstream: "https://github.com/zturtleman/lilium-voyager" +upstream: "https://github.com/clover-moe/lilium-voyager" profiled_date: "2026-03-25" source_commit: "58b70dd7ea891c2e8ddc37d03a5d58116b0ea118" core_version: "git" diff --git a/emulators/wolf4sdl.yml b/emulators/wolf4sdl.yml index 90659d12..c55166e5 100644 --- a/emulators/wolf4sdl.yml +++ b/emulators/wolf4sdl.yml @@ -1,8 +1,8 @@ emulator: Wolf4SDL type: standalone core_classification: game_engine -source: "https://github.com/AryanWolf3D/Wolf4SDL" -upstream: "https://github.com/AryanWolf3D/Wolf4SDL" +source: "https://github.com/KS-Presto/Wolf4SDL" +upstream: "https://github.com/KS-Presto/Wolf4SDL" profiled_date: "2026-10-20" source_commit: "dc8b250af35fb0ace68db5eb879490b50068c20e" core_version: "2.0" diff --git a/tests/test_profile_repositories.py b/tests/test_profile_repositories.py new file mode 100644 index 00000000..c00f94a8 --- /dev/null +++ b/tests/test_profile_repositories.py @@ -0,0 +1,55 @@ +"""A profile names each repository under the name its forge answers today. + +GitHub follows a renamed or transferred repository's old name in silence: +flycast2021 declared libretro/flycast, which answers as libretro/parallel-dc, +and reicast declared reicast/reicast-emulator, which answers as +skmp/reicast-emulator. profile_sync counts such a move as review work. This +test reads the forge answers profile_sync has cached and fails on any +profile still declaring an old name. Without a cache it has nothing to read +and skips. +""" + +from __future__ import annotations + +import sys +import unittest +from pathlib import Path + +import yaml + +REPO_ROOT = Path(__file__).resolve().parent.parent +sys.path.insert(0, str(REPO_ROOT / "scripts")) + +import upstream # noqa: E402 +from profile_sync import declared_repositories # noqa: E402 + +CACHE = Path(upstream.CACHE_DIR) +if not CACHE.is_absolute(): + CACHE = REPO_ROOT / CACHE + + +class DeclaredRepositoriesAreCurrent(unittest.TestCase): + def test_no_profile_declares_a_moved_repository(self) -> None: + if not (CACHE / "_api").is_dir(): + self.skipTest("no forge answers cached") + checked = 0 + moved = [] + for path in sorted((REPO_ROOT / "emulators").glob("*.yml")): + profile = yaml.safe_load(path.read_text(encoding="utf-8")) or {} + for field, _key, url in declared_repositories(profile): + repo = upstream.parse_repo(url) + if repo is None: + continue + current = upstream.current_slug(repo, str(CACHE), offline=True) + if current is None: + continue + checked += 1 + if current.lower() != repo.slug.lower(): + moved.append(f"{path.stem} {field}: {repo.slug} answers as {current}") + if not checked: + self.skipTest("no declared repository has a cached forge answer") + self.assertEqual(moved, []) + + +if __name__ == "__main__": + unittest.main() diff --git a/wiki/testing-guide.md b/wiki/testing-guide.md index 8f40f834..5414495d 100644 --- a/wiki/testing-guide.md +++ b/wiki/testing-guide.md @@ -39,7 +39,7 @@ Every module in `tests/`, by the area it guards. |------|----------|---------| | Core regression suites | synthetic | `test_e2e`, `test_audit_regressions`, `test_tool_messages` | | File resolution and identity | synthetic + collection | `test_adler32_resolution`, `test_agnostic_scan`, `test_agnostic_scan_mode`, `test_agnostic_scope`, `test_agnostic_substitute`, `test_archive_choice`, `test_bios_companions`, `test_bundled_identity`, `test_casefold_cache`, `test_db_aliases`, `test_declared_names`, `test_derivations`, `test_directory_entries`, `test_extra_identity`, `test_foreign_tree`, `test_foreign_tree_names`, `test_frontend_digest`, `test_game_data_homonyms`, `test_hashing`, `test_identity`, `test_md5_pack_context`, `test_name_tiebreak`, `test_nec_filing`, `test_owner_resolution`, `test_path_suffix`, `test_resolution_evidence`, `test_shipped_content`, `test_twin_declarations`, `test_validated_choice`, `test_variant_choice`, `test_variant_identity`, `test_zipped_member` | -| Verification, cross-reference and profile checks | synthetic + profiles | `test_crypto_aes`, `test_crypto_unique_data`, `test_crypto_verify`, `test_case_insensitive_platforms`, `test_checks_have_values`, `test_core_file_fills_declaration`, `test_cross_reference_sources`, `test_file_consumers`, `test_fileless_audit`, `test_gap_settlement`, `test_hidden_extras`, `test_flycast_layout`, `test_launcher_aliases`, `test_launcher_layer`, `test_native_mode`, `test_no_case_collisions`, `test_path_conflict_status`, `test_path_null_copies`, `test_profile_checks`, `test_romm_hash_rule`, `test_shared_groups`, `test_standalone_mode`, `test_undeclared_dedup`, `test_unplaced_extras`, `test_validation_scope`, `test_verify_all_dir`, `test_verify_emulator_evidence`, `test_verify_listing`, `test_verify_pack_choice` | +| Verification, cross-reference and profile checks | synthetic + profiles | `test_crypto_aes`, `test_crypto_unique_data`, `test_crypto_verify`, `test_case_insensitive_platforms`, `test_checks_have_values`, `test_core_file_fills_declaration`, `test_cross_reference_sources`, `test_file_consumers`, `test_fileless_audit`, `test_gap_settlement`, `test_hidden_extras`, `test_flycast_layout`, `test_launcher_aliases`, `test_launcher_layer`, `test_native_mode`, `test_no_case_collisions`, `test_path_conflict_status`, `test_path_null_copies`, `test_profile_checks`, `test_profile_repositories`, `test_romm_hash_rule`, `test_shared_groups`, `test_standalone_mode`, `test_undeclared_dedup`, `test_unplaced_extras`, `test_validation_scope`, `test_verify_all_dir`, `test_verify_emulator_evidence`, `test_verify_listing`, `test_verify_pack_choice` | | Packs and manifests | synthetic + real packs | `test_artifact_lock`, `test_atomic_artifacts`, `test_batocera_cores`, `test_deterministic_zip`, `test_emulator_pack_counts`, `test_finalize_pack_names`, `test_large_file_cache`, `test_libretro_layout`, `test_manifest_entry`, `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_required_only_archives`, `test_required_only_twins`, `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_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` |