🔒 Repository is read-only – file editing is disabled.

PaganLinux/tmp-audit-sum-staleness.py main

87 linii Raw ← Powrót
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
#!/usr/bin/env python3
"""Wykrywa receptury, w ktorych sumy SHA256 sa STARSZE niz ostatnia zmiana
wersji/zrodel - czyli sumy nie zostaly przeliczone po podbiciu pkgver.

To dokladnie klasa bledu, ktora wywolala problem z util-linux 2.42.2:
suma pochodzila z 2.41.x, a URL/pkgver zmieniono na 2.42.2.

Heurystyka oparta na historii git (bez pobierania plikow):
  idx_ver = najnowszy commit zmieniajacy 'pkgver:' lub 'source:'
  idx_sum = najnowszy commit zmieniajacy 'sha256sums:'
  jesli idx_ver < idx_sum (ver nowsze) -> suma moze byc nieaktualna
"""
import json
import os
import re
import subprocess
import sys

R = "/var/lib/pagan-sync/recipes"
LIMIT = 40
OUT = "/tmp/sum-staleness.json"


def git(*args):
    return subprocess.run(["git", "-C", R] + list(args), capture_output=True, text=True).stdout


def has_real_sums(path):
    try:
        import yaml
        d = yaml.safe_load(open(os.path.join(R, path), newline="", encoding="utf-8")) or {}
    except Exception:
        return False
    s = d.get("sha256sums")
    if not isinstance(s, list):
        return bool(s) and not str(s).strip().upper().startswith("SKIP")
    return any(not str(x).strip().upper().startswith("SKIP") for x in s)


def main():
    files = []
    for dp, _d, fs in os.walk(R):
        if "PAGBUILD.yaml" in fs and ".git" not in dp:
            p = os.path.relpath(os.path.join(dp, "PAGBUILD.yaml"), R)
            files.append(p)
    files.sort()
    print(f"receptur: {len(files)}", flush=True)

    suspects = []
    checked = 0
    for path in files:
        if not has_real_sums(path):
            continue
        commits = [c for c in git("log", "--format=%H", "-n", str(LIMIT), "--", path).split() if c]
        if not commits:
            continue
        checked += 1
        idx_ver = idx_sum = None
        ver_commit = sum_commit = None
        for i, c in enumerate(commits):
            d = git("show", "--format=", "--unified=0", c, "--", path)
            if idx_ver is None and re.search(r"^[+-](pkgver|source):", d, re.M):
                idx_ver, ver_commit = i, c
            if idx_sum is None and re.search(r"^[+-]sha256sums:", d, re.M):
                idx_sum, sum_commit = i, c
            if idx_ver is not None and idx_sum is not None:
                break
        if idx_ver is None:
            continue
        if idx_sum is None or idx_ver < idx_sum:
            suspects.append({
                "recipe": path,
                "ver_commit": ver_commit,
                "sum_commit": sum_commit,
                "ver_subject": git("log", "-1", "--format=%s", ver_commit).strip(),
                "sum_subject": git("log", "-1", "--format=%s", sum_commit).strip() if sum_commit else None,
            })
            print(f"SUSPECT {path}", flush=True)

    json.dump(suspects, open(OUT, "w"), indent=1, ensure_ascii=False)
    print(f"\nsprawdzono receptur z sumami: {checked}")
    print(f"podejrzanych (suma starsza niz zmiana wersji): {len(suspects)}")
    print(f"zapisano {OUT}")


if __name__ == "__main__":
    sys.exit(main())