Spaces:
Running
Running
File size: 4,470 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 48 49 50 51 52 | import json, os, html as H
from collections import Counter
R = []
for k in range(3):
p = f'results_N{k}.json'
if os.path.exists(p): R += json.load(open(p))
seen = set(); R = [r for r in R if not ((r['kind'], r['number']) in seen or seen.add((r['kind'], r['number'])))]
ACT = {'nudge': 'comment', 'superseded': 'close', 'obsolete': 'close', 'stale_close': 'close'}
cards = []
for r in R:
act = ACT.get(r['verdict'])
msg = r.get('message')
c = dict(kind=r['kind'], number=r['number'], title=r.get('title', ''), category=r['verdict'], area=r.get('area', 'other'),
confidence='high' if r.get('confidence') == 'high' else 'medium', by=None,
reason=f"[{r.get('area','?')}] {'BLOCKER: ' + r['blocker'] + ' · ' if r.get('blocker') else ''}WHY: {r.get('why','')} · EVIDENCE: {r.get('evidence','')}",
message=msg or ('(pointer comment already posted — nothing to send)' if r['kind'] == 'issue' and r['verdict'] == 'nudge' else ''))
if r['kind'] == 'issue' and r['verdict'] == 'nudge' and msg and r['number'] != 25178:
c['action'] = 'edit'; c['category'] = 'nudge'; c['reason'] = '[EDIT yesterday\'s pointer comment] ' + c['reason']
elif act == 'comment' and msg: c['action'] = 'comment'
elif act == 'close' and msg: pass
else: c['action'] = 'none'
cards.append(c)
order = ['nudge', 'maintainer_action', 'superseded', 'obsolete', 'stale_close', 'keep']
cards.sort(key=lambda c: (c['area'], order.index(c['category']) if c['category'] in order else 9, c['number']))
V = Counter(c['category'] for c in cards); A = Counter(c['area'] for c in cards)
areas = [a for a, _ in A.most_common()]
mat = Counter((c['area'], c['category']) for c in cards)
th = ''.join(f'<th>{v}</th>' for v in order)
rows = ''.join(f"<tr><td>{H.escape(a)}</td>" + ''.join(f"<td>{mat[(a,v)] or ''}</td>" for v in order) + f"<td><b>{A[a]}</b></td></tr>" for a in areas)
summary = (f"<details open><summary><b>{len(cards)} audited</b> — " + ' · '.join(f"{v} {V[v]}" for v in order) +
f"</summary><table class='mx'><tr><th>area</th>{th}<th>total</th></tr>{rows}</table>"
"<p class='why'>nudge = still valid on main + a concrete blocker the author can fix (comment only, stays open). "
"maintainer_action = ball is with us (approved / unreviewed / pending decision): no author nudge. "
"superseded / obsolete / stale_close = should close instead (evidence on each card). keep = active or maintainer-owned.</p></details>")
t = open('template4.html').read()
t = t.replace("DATA.forEach(a=>{if(!st[a.number])st[a.number]={d:'go'}}); // default: go\n", '')
t = t.replace("if(a.confidence!=='high'&&!isRead(a)){skipped++;return;} // unread check-cards = undecided; obvious ones export", "if(a.action==='none'){skipped++;return;}")
t = t.replace('<option>superseded</option><option>obsolete</option><option>stale</option><option>nudge</option>', ''.join(f'<option>{v}</option>' for v in order))
t = t.replace("if(f&&a.category!==f&&a.confidence!==f)return;", "if(f&&a.category!==f&&a.confidence!==f&&a.area!==f)return;")
t = t.replace('<option value="high">high only</option>', ''.join(f'<option value="{H.escape(a)}">area: {H.escape(a)}</option>' for a in areas) + '<option value="high">high only</option>')
t = t.replace("lines.push(a.action==='comment'?", "lines.push(a.action==='edit'?`gh-edit ${a.kind} ${a.number} ${q(m)}`:a.action==='comment'?")
assert 'gh-edit' in t
t = t.replace("const KEY='triage-open-prs-decisions';", "const KEY='triage-nudge-audit';")
t = t.replace('<b>transformers open PRs</b>', '<b>Nudge audit: PRs + issues</b>').replace('<title>Open PR Review</title>', '<title>Nudge Audit</title>')
t = t.replace("l.download='open_prs.sh'", "l.download='nudges.sh'").replace('Export gh script (read cards only)', 'Export gh script')
t = t.replace('<input type="checkbox" id="hideNudge" checked> hide nudges', '<input type="checkbox" id="hideNudge"> hide nudges')
t = t.replace('<input type="checkbox" id="showHigh">', '<input type="checkbox" id="showHigh" checked>')
t = t.replace('<div id="list"></div>', summary + '<div id="list"></div>')
t = t.replace('.tag{', '.mx{border-collapse:collapse;margin:8px 0;font-size:12px}.mx td,.mx th{border:1px solid var(--bd);padding:2px 8px;text-align:right}.mx td:first-child{text-align:left}\n.tag{')
open('nudges.html', 'w').write(t.replace('__DATA__', json.dumps(cards).replace('</', '<\\/')))
print(len(cards), dict(V))
|