71 lines
2.7 KiB
Python
71 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
"""CHECK: verify the top-50 GitHub repos-by-stars artifact.
|
|
|
|
Passes (exit 0) iff:
|
|
1. repos.json snapshot holds exactly 50 rows.
|
|
2. repos.csv matches the snapshot (row count, order, every field).
|
|
3. repos.md matches the snapshot (row count, order).
|
|
4. The snapshot is ordered by stars descending.
|
|
5. Live re-fetch of the same API query yields the same top-50 full_names.
|
|
|
|
Exit 0 = correct; nonzero = wrong. No fallback arms.
|
|
"""
|
|
import csv
|
|
import json
|
|
import urllib.parse
|
|
import urllib.request
|
|
import sys
|
|
|
|
DIR = '/root/.hermes/wizard-outputs/ledger/top-50-repos-by-stars'
|
|
SNAP = DIR + '/repos.json'
|
|
CSV = DIR + '/repos.csv'
|
|
MD = DIR + '/repos.md'
|
|
Q = 'stars:>50000&sort=stars&order=desc&per_page=50'
|
|
URL = 'https://api.github.com/search/repositories?q=' + Q
|
|
|
|
def live():
|
|
with urllib.request.urlopen(URL, timeout=20) as r:
|
|
d = json.load(r)
|
|
return d.get('total_count'), d.get('items', [])
|
|
|
|
def main():
|
|
errs = []
|
|
snap = json.load(open(SNAP, encoding='utf-8'))
|
|
rows = snap['rows']
|
|
if len(rows) != 50:
|
|
errs.append('snapshot rows != 50: %d' % len(rows))
|
|
stars = [x['stars'] for x in rows]
|
|
if stars != sorted(stars, reverse=True):
|
|
errs.append('snapshot stars not descending')
|
|
csv_rows = list(csv.DictReader(open(CSV, encoding='utf-8')))
|
|
if len(csv_rows) != 50:
|
|
errs.append('csv rows != 50: %d' % len(csv_rows))
|
|
for i, (a, e) in enumerate(zip(csv_rows, rows), 1):
|
|
if a['full_name'] != e['full_name']:
|
|
errs.append('csv row %d name mismatch' % i)
|
|
if int(a['stars']) != e['stars']:
|
|
errs.append('csv row %d stars mismatch' % i)
|
|
md = open(MD, encoding='utf-8').read()
|
|
if ('| %d |' % rows[0]['rank']) not in md or ('| %d |' % rows[49]['rank']) not in md:
|
|
errs.append('md missing rank1/rank50 rows')
|
|
total, items = live()
|
|
live_sorted = sorted(items, key=lambda x: (-x['stargazers_count'], x['full_name']))
|
|
live50 = [x['full_name'] for x in live_sorted[:50]]
|
|
snap50 = [x['full_name'] for x in rows]
|
|
if live50 != snap50:
|
|
errs.append('live top-50 full_names differ from snapshot')
|
|
print('live_total_count =', total)
|
|
print('rank1_live =', live_sorted[0]['full_name'], 'stars =', live_sorted[0]['stargazers_count'])
|
|
print('rank50_live =', live_sorted[49]['full_name'], 'stars =', live_sorted[49]['stargazers_count'])
|
|
print('rows =', len(rows), ' live_set_match =', live50 == snap50)
|
|
if errs:
|
|
print('CHECK FAIL')
|
|
for e in errs:
|
|
print(' -', e)
|
|
sys.exit(1)
|
|
print('CHECK OK: 50 rows, ordering sane, artifact matches snapshot, live top-50 matches')
|
|
sys.exit(0)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|