mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-20 10:23:16 -05:00
feat: file cards name the packs that install them
A card named only the platforms whose own list declares the file. A RetroBat user looking up scph5501.bin found every platform but RetroBat, whose pack installs it for six cores. The cards now read the install manifests and add each pack that places the file, with the destination it gives it.
This commit is contained in:
1 parent
91403aa149
commit
17e35d1af9
3 files changed
+62
No files matched your search
@@ -341,6 +341,9 @@ class FileConsumers:
|
||||
# Where each platform puts the file in its BIOS directory.
|
||||
self.platform_destinations: dict[str, dict[str, set[str]]] = {}
|
||||
self.emulators: dict[str, set[str]] = {}
|
||||
# Where each platform's pack installs the file, its cores' files
|
||||
# included: the platform's own list names a fraction of them.
|
||||
self.installed: dict[str, dict[str, set[str]]] = {}
|
||||
|
||||
def sha1_of(self, entry: dict, dest: str = "", owner: str = "") -> str | None:
|
||||
"""The collected file an entry resolves to, or None.
|
||||
@@ -378,6 +381,22 @@ class FileConsumers:
|
||||
name, set()
|
||||
).add(where)
|
||||
|
||||
def add_manifests(self, install_dir: str | Path) -> None:
|
||||
"""Read what each install manifest places, alternatives included."""
|
||||
for path in sorted(Path(install_dir).glob("*.json")):
|
||||
try:
|
||||
manifest = json.loads(path.read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError) as exc:
|
||||
print(f"WARNING: {path}: {exc}", file=sys.stderr)
|
||||
continue
|
||||
platform = str(manifest.get("platform") or path.stem)
|
||||
for entry in manifest.get("files") or []:
|
||||
for sha1 in {entry.get("sha1"), *(
|
||||
alt.get("sha1") for alt in entry.get("alternatives") or []
|
||||
)} - {None, ""}:
|
||||
self.installed.setdefault(sha1, {}).setdefault(
|
||||
platform, set()).add(str(entry.get("dest", "")))
|
||||
|
||||
def path_of(self, sha1: str) -> str:
|
||||
"""The collection path the database records for a file."""
|
||||
return str(self._db.get("files", {}).get(sha1, {}).get("path", ""))
|
||||
|
||||
@@ -2325,6 +2325,18 @@ def _platform_links(sha1: str, consumers: FileConsumers) -> list[str]:
|
||||
return links
|
||||
|
||||
|
||||
def _installed_links(sha1: str, consumers: FileConsumers, declared: set[str]) -> list[str]:
|
||||
"""Each pack installing the file that its platform's list does not name,
|
||||
with the place the pack gives it."""
|
||||
links = []
|
||||
for platform, dests in sorted(getattr(consumers, "installed", {}).get(sha1, {}).items()):
|
||||
if platform in declared:
|
||||
continue
|
||||
where = ", ".join(_code(d) for d in sorted(dests) if d)
|
||||
links.append(f"[{platform}](../platforms/{platform}.md)" + (f" {where}" if where else ""))
|
||||
return links
|
||||
|
||||
|
||||
def _system_file_card(f: dict, consumers: FileConsumers) -> list[str]:
|
||||
"""One file of a system page: hashes, who reads it, its provenance."""
|
||||
name = f["name"]
|
||||
@@ -2364,6 +2376,12 @@ def _system_file_card(f: dict, consumers: FileConsumers) -> list[str]:
|
||||
# that platform puts the file: from the card, retrodeck sent the
|
||||
# reader to the top of a 2,000-file page.
|
||||
lines.append(f"- Platforms: {', '.join(_platform_links(sha1_full, consumers))}")
|
||||
installed = _installed_links(sha1_full, consumers, set(plats))
|
||||
if installed:
|
||||
# The packs that carry the file for their cores: a RetroBat user
|
||||
# looking up scph5501.bin found every platform but RetroBat, whose
|
||||
# pack installs it for six cores.
|
||||
lines.append(f"- Also installed by: {', '.join(installed)}")
|
||||
if emus:
|
||||
lines.append(f"- Emulators: {', '.join(_emulator_link(e, '../') for e in emus)}")
|
||||
provenance = f.get("provenance", {})
|
||||
@@ -4117,6 +4135,7 @@ def _build_file_consumers(db: dict, coverages: dict, profiles: dict) -> FileCons
|
||||
consumers = FileConsumers(db, build_zip_contents_index(db))
|
||||
consumers.add_platforms({name: cov["config"] for name, cov in coverages.items()})
|
||||
consumers.add_emulators(profiles)
|
||||
consumers.add_manifests(Path(__file__).resolve().parent.parent / "install")
|
||||
return consumers
|
||||
|
||||
|
||||
|
||||
@@ -678,5 +678,29 @@ class AFileHasAnAddressByContent(unittest.TestCase):
|
||||
self.assertIn("../../files/?sha1=" + "ab" * 20, card)
|
||||
|
||||
|
||||
class ACardNamesThePacksThatInstallIt(unittest.TestCase):
|
||||
"""A file card named only the platforms whose own list declares the
|
||||
file: a RetroBat user found no RetroBat on scph5501.bin, which its pack
|
||||
installs for six cores."""
|
||||
|
||||
def test_a_manifest_destination_reaches_the_card(self):
|
||||
import json as _json
|
||||
|
||||
from cross_reference import FileConsumers
|
||||
from generate_site import _installed_links
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=ROOT / "tmp") as tmp:
|
||||
Path(tmp, "retrobat.json").write_text(_json.dumps({
|
||||
"platform": "retrobat",
|
||||
"files": [{"dest": "scph5501.bin", "sha1": "b" * 40,
|
||||
"alternatives": [{"sha1": "a" * 40}]}],
|
||||
}))
|
||||
consumers = FileConsumers({"files": {}})
|
||||
consumers.add_manifests(tmp)
|
||||
links = _installed_links("a" * 40, consumers, set())
|
||||
self.assertEqual(links, ["[retrobat](../platforms/retrobat.md) `scph5501.bin`"])
|
||||
self.assertEqual(_installed_links("a" * 40, consumers, {"retrobat"}), [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user