#!/usr/bin/env python3 """Audit source/deletion_lists_update.h against the OmniNX pack repo. Lists every update-mode deletion entry and whether the pack ships it now, shipped it in the past, or never did. Entries under switch/ or config/ that the pack never shipped are almost always user installs and should not be in the update list (see the header comment in deletion_lists_update.h). usage: python3 tools/audit_update_list.py ../OmniNX """ import re import subprocess import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] UPDATE_H = ROOT / "source" / "deletion_lists_update.h" PACK_PREFIX = re.compile(r"^(?:variants/[^/]+/(?:extras/hekate-ams-pro/)?|staging/)") # Not shipped as files, but reset on purpose during updates. INTENTIONAL = { "config/nx-hbmenu", # hbmenu settings (hbmenu.nro is shipped) "config/sys-patch", # sys-patch settings (sys-patch is shipped) "switch/tinfoil/db", # stale title DB cache } def pack_paths(repo: Path, all_history: bool) -> list[str]: if all_history: cmd = ["git", "-C", str(repo), "log", "--all", "--name-only", "--format=", "--", "variants", "staging"] else: cmd = ["git", "-C", str(repo), "ls-files", "variants", "staging"] out = subprocess.run(cmd, check=True, capture_output=True, text=True).stdout paths = set() for line in out.splitlines(): line = line.strip() if line and PACK_PREFIX.match(line): paths.add(PACK_PREFIX.sub("", line).lower()) return sorted(paths) def covered(paths: list[str], entry: str) -> bool: return any(p == entry or p.startswith(entry + "/") for p in paths) def main() -> int: if len(sys.argv) != 2: print(__doc__.strip()) return 2 repo = Path(sys.argv[1]) current = pack_paths(repo, all_history=False) history = pack_paths(repo, all_history=True) text = UPDATE_H.read_text(encoding="utf-8") suspicious = 0 for m in re.finditer(r"static const char\*\s+(\w+)\[\]\s*=\s*\{(.*?)\};", text, re.S): for entry in re.findall(r'"sd:/([^"]+)"', m.group(2)): e = entry.lower() if covered(current, e): state = "shipped" elif covered(history, e): state = "dropped" else: state = "never" flag = "" if state == "never" and e not in INTENTIONAL and (e.startswith("switch/") or e.startswith("config/")): flag = " <-- user install? remove from update list" suspicious += 1 print(f"{state:8} {m.group(1):36} {entry}{flag}") print(f"\n{suspicious} suspicious entr{'y' if suspicious == 1 else 'ies'}") return 1 if suspicious else 0 if __name__ == "__main__": sys.exit(main())