mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-18 09:23:26 -05:00
fix: find the branch in a URL into a folder
A /tree/<branch>/<dir> URL was read as one branch name, so the repository never resolved. Each prefix is tried, shortest first. A repository that answers nothing now says so, or reports the declared upstream_gone.
This commit is contained in:
1 parent
16c0b27213
commit
db3eba1cfc
3 files changed
+92
-6
No files matched your search
@@ -5,6 +5,7 @@ source: "https://github.com/kitao/pyxel"
|
||||
upstream: "https://github.com/kitao/pyxel"
|
||||
profiled_date: "2026-10-04"
|
||||
source_commit: "50f9bd77780c993aca62b5b221766bde5791081d"
|
||||
upstream_gone: "github.com/kitao/pyxel answers HTTP 404 to the API and the web, with no redirect. Observed 2026-10-18; no mirror found."
|
||||
core_version: "v2.9.9"
|
||||
display_name: "Pyxel"
|
||||
cores: [pyxel]
|
||||
|
||||
+36
-6
@@ -1293,15 +1293,19 @@ def select_views(
|
||||
# no profile carries, and fell back to profiled_date, which a bump
|
||||
# never moves (eden judged from f6e76860 while pinned on d16735f5).
|
||||
pin_field = "source" if field == "source_mirror" else field
|
||||
branch = branch_in_url(url) or (
|
||||
declared if pin_field == "source" else None
|
||||
)
|
||||
branch = declared if pin_field == "source" else None
|
||||
head = None
|
||||
for candidate in branch_candidates(url):
|
||||
head = upstream.resolve_head(repo, cache_dir, offline, candidate)
|
||||
if head:
|
||||
branch = candidate
|
||||
break
|
||||
pin, origin = resolve_pin(
|
||||
profile, repo, cache_dir, offline, pin_field, mode, branch
|
||||
)
|
||||
if not pin:
|
||||
continue
|
||||
head = upstream.resolve_head(repo, cache_dir, offline, branch)
|
||||
head = head or upstream.resolve_head(repo, cache_dir, offline, branch)
|
||||
if not head:
|
||||
continue
|
||||
seen.add((repo.host, repo.slug))
|
||||
@@ -1372,12 +1376,29 @@ 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.
|
||||
the repository and the branch the port lives on. The tail may go on into
|
||||
a directory (`.../libretro-samples/tree/master/tests/cruzes`): this is
|
||||
the whole tail, and branch_candidates() its prefixes.
|
||||
"""
|
||||
_, sep, tail = url.partition("/tree/")
|
||||
return tail.strip("/") or None if sep else None
|
||||
|
||||
|
||||
def branch_candidates(url: str) -> list[str]:
|
||||
"""Each prefix of a /tree/ tail, shortest first, that may be the branch.
|
||||
|
||||
A branch name can hold a slash, so the tail is not split blindly; the
|
||||
first prefix the forge resolves is the branch, the rest a directory.
|
||||
Taken whole, `master/tests/cruzes` resolved to nothing and the profile
|
||||
was skipped as having no resolvable pin.
|
||||
"""
|
||||
tail = branch_in_url(url)
|
||||
if not tail:
|
||||
return []
|
||||
parts = tail.split("/")
|
||||
return ["/".join(parts[:n]) for n in range(1, len(parts) + 1)]
|
||||
|
||||
|
||||
SELF_CHECK_CONTEXT = 2
|
||||
|
||||
|
||||
@@ -1632,9 +1653,18 @@ def build_report(
|
||||
f"upstream_gone is declared but the forge answers: {stated_gone}"
|
||||
)
|
||||
return report
|
||||
if not views and stated_gone:
|
||||
report.skipped = f"upstream gone (declared): {stated_gone}"
|
||||
return report
|
||||
if not views:
|
||||
# A declared pin whose repository or branch does not answer is not a
|
||||
# profile without a pin: pyxel's kitao/pyxel answers 404, and the
|
||||
# message sent the reader looking for a missing source_commit.
|
||||
report.skipped = (
|
||||
"no source_commit and no resolvable profiled_date "
|
||||
"no declared repository answers (moved, removed, or a branch the "
|
||||
"forge does not know)"
|
||||
if profile.get("source_commit") or profile.get("upstream_commit")
|
||||
else "no source_commit and no resolvable profiled_date "
|
||||
"on any declared repository"
|
||||
)
|
||||
return report
|
||||
|
||||
@@ -4070,5 +4070,60 @@ class TestSelectionNamesWhatMatchedNothing(unittest.TestCase):
|
||||
self.assertEqual(sorted(selected), ["handy", "mednafen_lynx"])
|
||||
|
||||
|
||||
|
||||
class TestTreeUrlIntoADirectory(unittest.TestCase):
|
||||
"""`.../libretro-samples/tree/master/tests/cruzes` took the whole tail as
|
||||
the branch; nothing resolved and cruzes was skipped as having no pin."""
|
||||
|
||||
def test_candidates_are_prefixes_shortest_first(self):
|
||||
self.assertEqual(
|
||||
profile_sync.branch_candidates(
|
||||
"https://github.com/libretro/libretro-samples/tree/master/tests/cruzes"
|
||||
),
|
||||
["master", "master/tests", "master/tests/cruzes"],
|
||||
)
|
||||
self.assertEqual(profile_sync.branch_candidates("https://github.com/o/r"), [])
|
||||
|
||||
def test_the_first_resolving_prefix_is_the_branch(self):
|
||||
from unittest import mock
|
||||
|
||||
asked = []
|
||||
|
||||
def head(repo, cache, offline=False, branch=None):
|
||||
asked.append(branch)
|
||||
return "tipsha" if branch == "master" else None
|
||||
|
||||
profile = {"source": "https://github.com/libretro/libretro-samples/tree/master/tests/cruzes",
|
||||
"source_commit": "pinsha"}
|
||||
with mock.patch.object(profile_sync.upstream, "resolve_head", side_effect=head):
|
||||
views = profile_sync.select_views(profile, ".cache", True)
|
||||
self.assertEqual([(v.pin, v.head) for v in views], [("pinsha", "tipsha")])
|
||||
self.assertEqual(asked[0], "master")
|
||||
|
||||
|
||||
|
||||
class TestAnUnansweringRepository(unittest.TestCase):
|
||||
"""pyxel declares source_commit, yet the skip read "no source_commit":
|
||||
its repository answers 404. A declared upstream_gone was honoured only
|
||||
when the forge raised GoneError, never on a plain non-answer."""
|
||||
|
||||
def _report(self, profile):
|
||||
from unittest import mock
|
||||
|
||||
with mock.patch.object(profile_sync, "select_views", return_value=[]):
|
||||
return profile_sync.build_report("p", profile, ".cache", True)
|
||||
|
||||
def test_a_declared_pin_names_the_repository(self):
|
||||
report = self._report({"source": "https://github.com/o/r", "source_commit": "abc",
|
||||
"files": [{"name": "a", "source_ref": "a.c:1"}]})
|
||||
self.assertIn("no declared repository answers", report.skipped)
|
||||
|
||||
def test_a_declared_gone_upstream_is_honoured(self):
|
||||
report = self._report({"source": "https://github.com/o/r", "source_commit": "abc",
|
||||
"upstream_gone": "404 since 2026-10-18",
|
||||
"files": [{"name": "a", "source_ref": "a.c:1"}]})
|
||||
self.assertEqual(report.skipped, "upstream gone (declared): 404 since 2026-10-18")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user