From 25f8537a4aa52336cb898c8fb7b54bd9420c2d44 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sat, 8 Aug 2026 06:19:38 +0200 Subject: [PATCH] fix: point manifest entries at a fetchable file --- scripts/generate_pack.py | 9 +++++---- tests/test_e2e.py | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/scripts/generate_pack.py b/scripts/generate_pack.py index d429fc33..87cdf6fa 100644 --- a/scripts/generate_pack.py +++ b/scripts/generate_pack.py @@ -3179,14 +3179,15 @@ def generate_manifest( if status in ("not_found", "external"): continue - # Get SHA1 and size + # Get SHA1 and size. The installer fetches by hash, so record + # the copy this repo holds: an upstream hash carried by no + # local file resolves to no download URL at all. sha1 = file_entry.get("sha1", "") file_size = 0 if local_path and os.path.exists(local_path): file_size = os.path.getsize(local_path) - if not sha1: - hashes = compute_hashes(local_path) - sha1 = hashes["sha1"] + if not sha1 or not _get_repo_path(sha1, db): + sha1 = compute_hashes(local_path)["sha1"] repo_path = _get_repo_path(sha1, db) if sha1 else "" diff --git a/tests/test_e2e.py b/tests/test_e2e.py index bbc1d5f2..2d7bdbd9 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -3406,6 +3406,49 @@ class TestE2E(unittest.TestCase): self.assertIsInstance(f["size"], int) self.assertGreater(len(f["sha1"]), 0) + def test_91b_manifest_hash_points_at_a_fetchable_file(self): + """A declared hash no local file carries must not blank repo_path. + + install.py builds its download URL from repo_path, so an upstream + hash that resolves to nothing leaves the file unfetchable. + """ + from generate_pack import generate_manifest + + registry_path = os.path.join(self.platforms_dir, "_test_registry2.yml") + with open(registry_path, "w") as fh: + yaml.dump({"platforms": {"test_existence": {"install": {}}}}, fh) + + config_path = os.path.join(self.platforms_dir, "test_existence.yml") + with open(config_path) as fh: + config = yaml.safe_load(fh) + for system in config.get("systems", {}).values(): + for entry in system.get("files", []): + entry["sha1"] = "0" * 40 # upstream hash, absent from the repo + with open(config_path, "w") as fh: + yaml.dump(config, fh) + from common import _platform_config_cache + + _platform_config_cache.clear() + + manifest = generate_manifest( + "test_existence", + self.platforms_dir, + self.db, + self.bios_dir, + registry_path, + emulators_dir=self.emulators_dir, + ) + + self.assertGreater(len(manifest["files"]), 0) + for f in manifest["files"]: + if f.get("release_asset"): + continue + self.assertTrue( + f["repo_path"], + f"{f['dest']} has no repo_path, install.py cannot fetch it", + ) + self.assertNotEqual(f["sha1"], "0" * 40) + def test_92_manifest_matches_zip(self): """Manifest file destinations match ZIP contents (excluding metadata).""" from generate_pack import generate_manifest, generate_pack