Spaces:
Running
Running
File size: 3,499 Bytes
cc857c8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | import json, re, subprocess, sys
from collections import Counter
from datetime import datetime, timezone
prs = json.load(open(sys.argv[1]))
closed = set(int(l.split()[0]) for l in open("close_fail.log")) if False else set()
done = set(int(m) for m in re.findall(r"close (\d+)", open("cmds.sh").read()))
main = set(subprocess.run(["git", "-C", "/Users/arthurzucker/Work/transformers", "ls-tree", "-r", "--name-only", "origin/main"],
capture_output=True, text=True).stdout.split())
NOW = datetime(2026, 10, 20, tzinfo=timezone.utc)
age = lambda s: (NOW - datetime.fromisoformat(s.replace("Z", "+00:00"))).days
PHIL = [(re.compile(r"modeling_(tf|flax)_|_tf_utils|_flax_utils|/tf_|/flax_"), "TF/Flax code (removed in v5)"),
(re.compile(r"^examples/research_projects/|^examples/legacy/|^templates/|^examples/(tensorflow|flax)/"), "removed/legacy examples or templates"),
(re.compile(r"^src/transformers/models/deprecated/"), "deprecated model"),
(re.compile(r"^src/transformers/(benchmark|onnx|commands/(pt_to_tf|convert))/"), "removed subsystem (benchmark/onnx/pt_to_tf)")]
out = []
for p in prs:
if p["number"] in done: continue
files = [f["path"] for f in p["files"]["nodes"]]
last_commit = age(p["commits"]["nodes"][0]["commit"]["committedDate"]) if p["commits"]["nodes"] else 9999
upd = age(p["updatedAt"])
# new modeling files added count as present only if PR adds them; missing = existing-path edits that vanished
missing = [f for f in files if f not in main and not re.search(r"models/[^/]+/(modeling|modular|configuration|processing|image_processing|tokenization|convert)_|^tests/models/|^docs/", f)]
reasons, cats = [], set()
if p["baseRefName"] != "main":
cats.add("old_branch"); reasons.append(f"base branch is `{p['baseRefName']}`")
if files and len(missing) / len(files) >= 0.5:
cats.add("old_branch"); reasons.append(f"{len(missing)}/{len(files)} touched files no longer exist on main")
for rx, why in PHIL:
hits = [f for f in files if rx.search(f)]
if hits: cats.add("philosophy"); reasons.append(f"{why}: {hits[0]}" + (f" (+{len(hits)-1})" if len(hits) > 1 else ""))
if last_commit > 365 and upd > 90:
cats.add("outdated"); reasons.append(f"last commit {last_commit}d ago, last activity {upd}d ago")
elif p["mergeable"] == "CONFLICTING" and last_commit > 180 and upd > 60:
cats.add("outdated"); reasons.append(f"merge conflicts, last commit {last_commit}d ago")
if cats:
out.append({"number": p["number"], "title": p["title"], "author": (p["author"] or {}).get("login"),
"assoc": p["authorAssociation"], "draft": p["isDraft"], "base": p["baseRefName"],
"mergeable": p["mergeable"], "review": p["reviewDecision"], "created": p["createdAt"][:10],
"last_commit_days": last_commit, "updated_days": upd, "labels": [l["name"] for l in p["labels"]["nodes"]],
"files": files[:15], "nfiles": p["files"]["totalCount"], "cats": sorted(cats), "signals": reasons,
"last_comments": [{"by": (c["author"] or {}).get("login"), "assoc": c["authorAssociation"], "at": c["createdAt"][:10], "text": c["body"][:300]} for c in p["comments"]["nodes"]]})
json.dump(out, open(sys.argv[2], "w"), indent=1)
print(len(prs), "open PRs ->", len(out), "flagged;", Counter(c for o in out for c in o["cats"]))
print("assoc:", Counter(o["assoc"] for o in out))
|