mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 13:33:24 -05:00
feat: read per-mode sources and pins
This commit is contained in:
1 parent
4a69b96922
commit
49f50f51b5
4 files changed
+74
-20
No files matched your search
+8
-6
@@ -3,10 +3,12 @@ type: standalone + libretro
|
|||||||
core_classification: community_fork
|
core_classification: community_fork
|
||||||
source:
|
source:
|
||||||
standalone: "https://github.com/StrikerX3/Ymir"
|
standalone: "https://github.com/StrikerX3/Ymir"
|
||||||
libretro: "https://github.com/warmenhoven/Ymir/tree/libretro"
|
libretro: "https://github.com/warmenhoven/Emir/tree/libretro"
|
||||||
upstream: "https://github.com/StrikerX3/Ymir"
|
upstream: "https://github.com/StrikerX3/Ymir"
|
||||||
profiled_date: "2026-03-26"
|
profiled_date: "2026-03-26"
|
||||||
source_commit: "5e9310410baa47cb7da5b068f399c9e4a34eedbc"
|
source_commit:
|
||||||
|
standalone: "5e9310410baa47cb7da5b068f399c9e4a34eedbc"
|
||||||
|
libretro: "5d99cbbf813206736f38b3574ecca7a8aedc07e5"
|
||||||
core_version:
|
core_version:
|
||||||
standalone: "v0.2.1"
|
standalone: "v0.2.1"
|
||||||
libretro: "PR#746"
|
libretro: "PR#746"
|
||||||
@@ -54,7 +56,7 @@ files:
|
|||||||
description: "Saturn IPL ROM (BIOS). Any region accepted."
|
description: "Saturn IPL ROM (BIOS). Any region accepted."
|
||||||
source_ref:
|
source_ref:
|
||||||
standalone: "apps/ymir-sdl3/src/util/rom_loader.cpp:9-22, apps/ymir-sdl3/src/app/rom_manager.cpp:14-56, libs/ymir-core/include/ymir/sys/memory_defs.hpp:9"
|
standalone: "apps/ymir-sdl3/src/util/rom_loader.cpp:9-22, apps/ymir-sdl3/src/app/rom_manager.cpp:14-56, libs/ymir-core/include/ymir/sys/memory_defs.hpp:9"
|
||||||
libretro: "libretro.cpp:260-263,534-558"
|
libretro: "apps/ymir-libretro/src/libretro.cpp:260-263,534-558"
|
||||||
|
|
||||||
- name: "cdb/cdb_rom.bin"
|
- name: "cdb/cdb_rom.bin"
|
||||||
system: sega-saturn
|
system: sega-saturn
|
||||||
@@ -65,7 +67,7 @@ files:
|
|||||||
description: "SH1 CD Block ROM for low-level CD drive emulation. Scans cdb/ subdirectory for any matching file."
|
description: "SH1 CD Block ROM for low-level CD drive emulation. Scans cdb/ subdirectory for any matching file."
|
||||||
source_ref:
|
source_ref:
|
||||||
standalone: "apps/ymir-sdl3/src/util/rom_loader.cpp:25-38, apps/ymir-sdl3/src/app/rom_manager.cpp:58-93, libs/ymir-core/include/ymir/hw/sh1/sh1_defs.hpp:7"
|
standalone: "apps/ymir-sdl3/src/util/rom_loader.cpp:25-38, apps/ymir-sdl3/src/app/rom_manager.cpp:58-93, libs/ymir-core/include/ymir/hw/sh1/sh1_defs.hpp:7"
|
||||||
libretro: "libretro.cpp:567-591"
|
libretro: "apps/ymir-libretro/src/libretro.cpp:565-591"
|
||||||
|
|
||||||
- name: "mpr-18811-mx.ic1"
|
- name: "mpr-18811-mx.ic1"
|
||||||
system: sega-saturn
|
system: sega-saturn
|
||||||
@@ -76,7 +78,7 @@ files:
|
|||||||
description: "ROM cartridge for The King of Fighters '95."
|
description: "ROM cartridge for The King of Fighters '95."
|
||||||
source_ref:
|
source_ref:
|
||||||
standalone: "apps/ymir-sdl3/src/app/rom_manager.cpp:96-131, libs/ymir-core/include/ymir/db/rom_cart_db.hpp:19-22"
|
standalone: "apps/ymir-sdl3/src/app/rom_manager.cpp:96-131, libs/ymir-core/include/ymir/db/rom_cart_db.hpp:19-22"
|
||||||
libretro: "libretro.cpp:619-620,597-616"
|
libretro: "apps/ymir-libretro/src/libretro.cpp:621, 598-618"
|
||||||
|
|
||||||
- name: "mpr-19367-mx.ic1"
|
- name: "mpr-19367-mx.ic1"
|
||||||
system: sega-saturn
|
system: sega-saturn
|
||||||
@@ -87,4 +89,4 @@ files:
|
|||||||
description: "ROM cartridge for Ultraman: Hikari no Kyojin Densetsu."
|
description: "ROM cartridge for Ultraman: Hikari no Kyojin Densetsu."
|
||||||
source_ref:
|
source_ref:
|
||||||
standalone: "apps/ymir-sdl3/src/app/rom_manager.cpp:96-131, libs/ymir-core/include/ymir/db/rom_cart_db.hpp:25-28"
|
standalone: "apps/ymir-sdl3/src/app/rom_manager.cpp:96-131, libs/ymir-core/include/ymir/db/rom_cart_db.hpp:25-28"
|
||||||
libretro: "libretro.cpp:619,621,597-616"
|
libretro: "apps/ymir-libretro/src/libretro.cpp:622, 598-618"
|
||||||
@@ -84,10 +84,26 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"source_commit": {
|
"source_commit": {
|
||||||
"type": "string"
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Revision the profile was read at; an object keys it by build mode when the builds live in different repositories."
|
||||||
},
|
},
|
||||||
"upstream_commit": {
|
"upstream_commit": {
|
||||||
"type": "string"
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Revision the profile was read at; an object keys it by build mode when the builds live in different repositories."
|
||||||
},
|
},
|
||||||
"profiled_date": {
|
"profiled_date": {
|
||||||
"description": "Quote it: an unquoted YAML date parses to a date object.",
|
"description": "Quote it: an unquoted YAML date parses to a date object.",
|
||||||
|
|||||||
+46
-10
@@ -659,20 +659,28 @@ def select_repo(profile: dict) -> upstream.Repo | None:
|
|||||||
|
|
||||||
|
|
||||||
def resolve_pin(
|
def resolve_pin(
|
||||||
profile: dict, repo, cache_dir: str, offline: bool, field: str = "source"
|
profile: dict, repo, cache_dir: str, offline: bool, field: str = "source",
|
||||||
|
mode: str = "", branch: str | None = None,
|
||||||
) -> tuple[str | None, str | None]:
|
) -> tuple[str | None, str | None]:
|
||||||
"""Commit the profile was written at, and how it was obtained.
|
"""Commit the profile was written at, and how it was obtained.
|
||||||
|
|
||||||
`field` selects which declared pin applies: `source_commit` for the port
|
`field` selects which declared pin applies: `source_commit` for the port
|
||||||
the profile was read from, `upstream_commit` for the original project.
|
the profile was read from, `upstream_commit` for the original project.
|
||||||
|
A profile whose builds live in different repositories keys its pin by
|
||||||
|
build mode, the way `ymir` keys `source` and `core_version`.
|
||||||
"""
|
"""
|
||||||
pinned = profile.get(f"{field}_commit")
|
pinned = profile.get(f"{field}_commit")
|
||||||
|
if isinstance(pinned, dict):
|
||||||
|
pinned = pinned.get(mode)
|
||||||
|
origin = f"{field}_commit[{mode}]"
|
||||||
|
else:
|
||||||
|
origin = f"{field}_commit"
|
||||||
if pinned:
|
if pinned:
|
||||||
return str(pinned), f"{field}_commit"
|
return str(pinned), origin
|
||||||
date = str(profile.get("profiled_date") or "")
|
date = str(profile.get("profiled_date") or "")
|
||||||
if not date:
|
if not date:
|
||||||
return None, None
|
return None, None
|
||||||
sha = upstream.resolve_commit_at(repo, date, cache_dir, offline)
|
sha = upstream.resolve_commit_at(repo, date, cache_dir, offline, branch)
|
||||||
return sha, (f"profiled_date {date}" if sha else None)
|
return sha, (f"profiled_date {date}" if sha else None)
|
||||||
|
|
||||||
|
|
||||||
@@ -689,17 +697,18 @@ def select_views(
|
|||||||
seen: set[tuple[str, str]] = set()
|
seen: set[tuple[str, str]] = set()
|
||||||
# A port living on a branch of a fork is absent from the default tip, so
|
# A port living on a branch of a fork is absent from the default tip, so
|
||||||
# the branch it was read from is followed when the profile names one.
|
# the branch it was read from is followed when the profile names one.
|
||||||
branch = str(profile.get("source_branch") or "") or None
|
declared = str(profile.get("source_branch") or "") or None
|
||||||
for field in ("source", "upstream"):
|
for field, mode, url in declared_repositories(profile):
|
||||||
repo = upstream.parse_repo(str(profile.get(field) or ""))
|
repo = upstream.parse_repo(url)
|
||||||
if repo is None or (repo.host, repo.slug) in seen:
|
if repo is None or (repo.host, repo.slug) in seen:
|
||||||
continue
|
continue
|
||||||
pin, origin = resolve_pin(profile, repo, cache_dir, offline, field)
|
branch = branch_in_url(url) or (declared if field == "source" else None)
|
||||||
|
pin, origin = resolve_pin(
|
||||||
|
profile, repo, cache_dir, offline, field, mode, branch
|
||||||
|
)
|
||||||
if not pin:
|
if not pin:
|
||||||
continue
|
continue
|
||||||
head = upstream.resolve_head(
|
head = upstream.resolve_head(repo, cache_dir, offline, branch)
|
||||||
repo, cache_dir, offline, branch if field == "source" else None
|
|
||||||
)
|
|
||||||
if not head:
|
if not head:
|
||||||
continue
|
continue
|
||||||
seen.add((repo.host, repo.slug))
|
seen.add((repo.host, repo.slug))
|
||||||
@@ -707,6 +716,33 @@ def select_views(
|
|||||||
return views
|
return views
|
||||||
|
|
||||||
|
|
||||||
|
def declared_repositories(profile: dict) -> list[tuple[str, str, str]]:
|
||||||
|
"""Every repository URL the profile declares, source before upstream.
|
||||||
|
|
||||||
|
`source` and `upstream` are usually plain strings. `ymir` keys them by
|
||||||
|
build mode instead, because its standalone and libretro builds live in
|
||||||
|
different repositories.
|
||||||
|
"""
|
||||||
|
urls: list[tuple[str, str, str]] = []
|
||||||
|
for field in ("source", "upstream"):
|
||||||
|
value = profile.get(field)
|
||||||
|
if isinstance(value, dict):
|
||||||
|
urls.extend((field, str(k), str(v)) for k, v in value.items() if v)
|
||||||
|
elif value:
|
||||||
|
urls.append((field, "", str(value)))
|
||||||
|
return urls
|
||||||
|
|
||||||
|
|
||||||
|
def branch_in_url(url: str) -> str | None:
|
||||||
|
"""Branch named by a forge URL pointing inside a repository.
|
||||||
|
|
||||||
|
A profile can cite a fork as `.../Ymir/tree/libretro`, which names both
|
||||||
|
the repository and the branch the port lives on.
|
||||||
|
"""
|
||||||
|
_, sep, tail = url.partition("/tree/")
|
||||||
|
return tail.strip("/") or None if sep else None
|
||||||
|
|
||||||
|
|
||||||
SELF_CHECK_CONTEXT = 2
|
SELF_CHECK_CONTEXT = 2
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1242,7 +1242,7 @@ class TestRunResilience(unittest.TestCase):
|
|||||||
self._orig = profile_sync.upstream.resolve_commit_at
|
self._orig = profile_sync.upstream.resolve_commit_at
|
||||||
self.seen: list[str] = []
|
self.seen: list[str] = []
|
||||||
|
|
||||||
def flaky(repo, date, cache_dir, offline=False):
|
def flaky(repo, date, cache_dir, offline=False, branch=None):
|
||||||
self.seen.append(repo.slug)
|
self.seen.append(repo.slug)
|
||||||
if repo.slug == "o/bad":
|
if repo.slug == "o/bad":
|
||||||
raise profile_sync.upstream.UpstreamError("HTTP 401")
|
raise profile_sync.upstream.UpstreamError("HTTP 401")
|
||||||
@@ -1265,7 +1265,7 @@ class TestRunResilience(unittest.TestCase):
|
|||||||
build_report("bad", profile, self.tmp.name)
|
build_report("bad", profile, self.tmp.name)
|
||||||
|
|
||||||
def test_rate_limit_still_propagates(self):
|
def test_rate_limit_still_propagates(self):
|
||||||
def limited(repo, date, cache_dir, offline=False):
|
def limited(repo, date, cache_dir, offline=False, branch=None):
|
||||||
raise profile_sync.upstream.RateLimitError("HTTP 403")
|
raise profile_sync.upstream.RateLimitError("HTTP 403")
|
||||||
|
|
||||||
profile_sync.upstream.resolve_commit_at = limited
|
profile_sync.upstream.resolve_commit_at = limited
|
||||||
|
|||||||
Reference in new issue
Block a user