From 4522f3ba01f7df6d8a5ef98ba20edb181856f5d4 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Tue, 27 Oct 2026 05:55:10 +0100 Subject: [PATCH] fix: keep the paths of a tree no folder lists A repository that answers 404 (TeknoParrotUI) was listed folder by folder, every listing failed, and the tree read as holding nothing: a fetch without its cached tree dropped its recorded paths. It is now unread, so the record keeps what it held. --- scripts/sitesources.py | 8 ++++++-- tests/test_site_r4_reference.py | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/scripts/sitesources.py b/scripts/sitesources.py index 5974e3c4e..c0270a5e9 100644 --- a/scripts/sitesources.py +++ b/scripts/sitesources.py @@ -272,10 +272,13 @@ def _listed_directories( """The cited paths found by listing their directories one by one, for a tree the forge truncates (aps3e vendors RPCS3 whole). A directory that cannot be listed confirms none of its paths. None off GitHub, the one - forge with that call.""" + forge with that call, and None when no directory could be listed: the + tree was not read, so its record is kept (TeknoParrotUI answers 404, and + each fetch without its cached tree dropped its four paths).""" if repo.family != "github": return None found: set[str] = set() + listed = False for folder in sorted({path.rpartition("/")[0] for path in paths} - {""}): names = None for index, cache_dir in enumerate(cache_dirs): @@ -286,8 +289,9 @@ def _listed_directories( names = None if names is not None: break + listed = listed or names is not None found.update(f"{folder}/{name}" for name in names or ()) - return frozenset(found) + return frozenset(found) if listed else None def build_source_paths( diff --git a/tests/test_site_r4_reference.py b/tests/test_site_r4_reference.py index b11a9cba0..6100cae49 100644 --- a/tests/test_site_r4_reference.py +++ b/tests/test_site_r4_reference.py @@ -232,6 +232,19 @@ class SourceLinksOnlyWhereTheFileIs(unittest.TestCase): self.assertEqual(held, {"github.com/o/r@" + "e" * 40: ["src/a.c", "src/c.c"]}) self.assertEqual(unread, []) + def test_a_tree_no_directory_answers_for_stays_unread(self): + # TeknoParrotUI answers 404: listed folder by folder, every listing + # failed and the tree read as holding nothing, so a fetch without its + # cached tree dropped its four recorded paths. + profile = {"source": "https://github.com/o/r", "source_commit": "e" * 40, + "files": [{"source_ref": "src/a.c:5"}]} + with mock.patch.object(sitesources, "_cached_tree", return_value=None), \ + mock.patch.object(sitesources.upstream, "list_directory", + side_effect=upstream.UpstreamError("HTTP 404")): + held, unread = sitesources.build_source_paths({"p": profile}, [TMP]) + self.assertEqual(held, {}) + self.assertEqual(unread, ["github.com/o/r@" + "e" * 40]) + def test_every_rendered_link_is_recorded(self): record = json.loads(sitesources.SOURCE_PATHS.read_text(encoding="utf-8")) pages = sorted(_built(DOCS / "emulators").rglob("*.md*")) + sorted(DOCS.glob("gaps*.md*"))