| #!/usr/bin/env python3 |
| # Show or diff test_summary output to latest posted test result for a platform |
| # test_summary -t | diffsummary.py (compare test result from current build to last posted) |
| # diffsummary.py --show (only show last posted) |
| from urllib.request import urlopen |
| from html.parser import HTMLParser |
| import time |
| import re |
| import argparse |
| import platform |
| import tempfile |
| import os |
| import sys |
| |
| baseurl = "https://gcc.gnu.org/pipermail/gcc-testresults/" |
| |
| ap = argparse.ArgumentParser(description="Diff stdin to latest posted test result and set exit code to result") |
| ap.add_argument("--branch", default="experimental", |
| help="Branch to match (regex substring match)") |
| ap.add_argument("--arch", default=platform.machine() + ".*" + platform.system().lower(), |
| help="architecture to match (regex substring match)") |
| ap.add_argument("--retrytime", default=1, type=int, |
| help="time to wait before fetching next page (fractional seconds)") |
| ap.add_argument("--show", help="Show last test result, but do not diff", action="store_true", default=False) |
| ap.add_argument("--url", help="Show URLs downloaded", action="store_true") |
| ap.add_argument("--diff", help="Diff program to use (default diff)", default="diff") |
| ap.add_argument("--diff-args", help="Diff arguments to use (default -u)", default="-u") |
| ap.add_argument("--skip", type=int, default=0, help="Skip first N posted test results") |
| args = ap.parse_args() |
| |
| class ParseMonths(HTMLParser): |
| def __init__(self): |
| super().__init__() |
| self.months = [] |
| def handle_starttag(self, tag, attrs): |
| if tag == "a" and "thread.html" in attrs[0][1]: |
| self.months.append(attrs[0][1]) |
| |
| class ParseThread(HTMLParser): |
| def __init__(self): |
| super().__init__() |
| self.link = None |
| self.target = [] |
| def handle_starttag(self, tag, attrs): |
| if (tag == "a" |
| and attrs[0][1][0].isdigit() |
| and attrs[0][1].endswith(".html")): |
| self.link = attrs[0][1] |
| else: |
| self.link = None |
| def handle_data(self, data): |
| if (self.link |
| and re.search(args.branch, data) |
| and re.search(args.arch, data)): |
| self.target.append(thread.link) |
| |
| class ParseArticle(HTMLParser): |
| def __init__(self): |
| super().__init__() |
| self.contents = None |
| self.pre = False |
| self.data = None |
| def handle_starttag(self, tag, attrs): |
| self.pre = tag == "pre" |
| def handle_data(self, data): |
| if self.pre and not self.data: |
| self.data = data |
| |
| def my_urlopen(url): |
| if args.url: |
| print(url) |
| return urlopen(url) |
| |
| with my_urlopen(baseurl) as index: |
| months = ParseMonths() |
| months.feed(index.read().decode('utf-8')) |
| if len(months.months) == 0: |
| sys.exit("no months found") |
| for month in months.months: |
| with my_urlopen(baseurl + month) as m: |
| thread = ParseThread() |
| thread.feed(m.read().decode('utf-8')) |
| if thread.target: |
| if args.skip > len(thread.target): |
| args.skip -= len(thread.target) |
| continue |
| url = (baseurl + month).replace("thread.html", thread.target[-1 - args.skip]) |
| with my_urlopen(url) as t: |
| article = ParseArticle() |
| article.feed(t.read().decode('utf-8')) |
| if args.show: |
| print(article.data) |
| break |
| with tempfile.NamedTemporaryFile(delete=False) as tf: |
| tf.write(article.data.encode('utf-8')) |
| tf.close() |
| cmd = f"{args.diff} {args.diff_args} - {tf.name}" |
| print(cmd) |
| ret = os.system(cmd) |
| os.unlink(tf.name) |
| sys.exit(ret) |
| break |
| time.sleep(args.retrytime) |