From 47e0e8d120f8d091d36b3439729e73d8aff69bba Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 6 Nov 2026 08:52:58 +0100 Subject: [PATCH] fix: database paths must be committed or ignored The manifest guard compared repo_path with database.json only, so a git mv under bios/ committed without regenerating either left both naming the old path and every test passed. A new test requires each database path to be tracked or gitignored, and a manifest entry whose repo_path git neither holds nor ignores now fails as untracked. --- tests/test_audit_regressions.py | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index 388a7cd0c..35e200ba0 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -2296,7 +2296,9 @@ class EveryManifestEntryIsFetchable(unittest.TestCase): else "gitignored" if repo_path in ignored else "untracked, never committed" ) - if bool(entry.get("release_asset")) != (state == "gitignored"): + if state == "untracked, never committed" or ( + bool(entry.get("release_asset")) != (state == "gitignored") + ): wrong.append((entry["dest"], repo_path, state)) self.assertEqual(wrong, [], f"{name} picks the wrong source: {wrong[:3]}") @@ -2310,6 +2312,36 @@ class EveryManifestEntryIsFetchable(unittest.TestCase): self.skipTest("not a git checkout") self.assertEqual(sorted(untracked)[:20], [], f"{len(untracked)} untracked files under bios/") + def test_every_database_path_is_committed_or_a_release_asset(self): + """A git mv under bios/ committed without regenerating anything left + database.json and the manifests agreeing on the old path: the tests + above compare them with each other, so all passed, and the installer + got a 404 (issue 78, with the database stale too).""" + database = ROOT / "database.json" + if not database.is_file(): + self.skipTest("database.json not generated") + files = json.loads(database.read_text(encoding="utf-8"))["files"] + paths = { + path + for entry in files.values() + for path in [entry.get("path"), *(entry.get("paths") or [])] + if path + } + tracked = _git_paths("ls-files", "-z") + if tracked is None: + self.skipTest("not a git checkout") + outside = sorted(paths - tracked) + ignored = _git_paths("check-ignore", "-z", "--no-index", "--stdin", stdin=outside) + if ignored is None: + self.skipTest("not a git checkout") + stale = [path for path in outside if path not in ignored] + self.assertEqual( + stale[:20], [], + f"{len(stale)} database paths git neither holds nor ignores: " + "python scripts/generate_db.py --force --bios-dir bios --output database.json, " + "then the manifests", + ) + class ReleaseAssetCriterion(unittest.TestCase): """What decides whether the installer fetches from the release is git, not size.