at 18.09-beta 2.9 kB view raw
1#!/usr/bin/env nix-shell 2#!nix-shell -i python3 -p 'python3.withPackages(ps: with ps; [ requests pyquery click ])' 3 4# To use, just execute this script with --help to display help. 5 6import subprocess 7import json 8import sys 9 10import click 11import requests 12from pyquery import PyQuery as pq 13 14 15maintainers_json = subprocess.check_output([ 16 'nix-instantiate', '-E', 'import ./maintainers/maintainer-list.nix {}', '--eval', '--json' 17]) 18maintainers = json.loads(maintainers_json) 19MAINTAINERS = {v: k for k, v in maintainers.items()} 20 21 22def get_response_text(url): 23 return pq(requests.get(url).text) # IO 24 25EVAL_FILE = { 26 'nixos': 'nixos/release.nix', 27 'nixpkgs': 'pkgs/top-level/release.nix', 28} 29 30 31def get_maintainers(attr_name): 32 try: 33 nixname = attr_name.split('.') 34 meta_json = subprocess.check_output([ 35 'nix-instantiate', 36 '--eval', 37 '--strict', 38 '-A', 39 '.'.join(nixname[1:]) + '.meta', 40 EVAL_FILE[nixname[0]], 41 '--json']) 42 meta = json.loads(meta_json) 43 if meta.get('maintainers'): 44 return [MAINTAINERS[name] for name in meta['maintainers'] if MAINTAINERS.get(name)] 45 except: 46 return [] 47 48def print_build(table_row): 49 a = pq(table_row)('a')[1] 50 print("- [ ] [{}]({})".format(a.text, a.get('href')), flush=True) 51 52 maintainers = get_maintainers(a.text) 53 if maintainers: 54 print(" - maintainers: {}".format(", ".join(map(lambda u: '@' + u, maintainers)))) 55 # TODO: print last three persons that touched this file 56 # TODO: pinpoint the diff that broke this build, or maybe it's transient or maybe it never worked? 57 58 sys.stdout.flush() 59 60@click.command() 61@click.option( 62 '--jobset', 63 default="nixos/release-17.09", 64 help='Hydra project like nixos/release-17.09') 65def cli(jobset): 66 """ 67 Given a Hydra project, inspect latest evaluation 68 and print a summary of failed builds 69 """ 70 71 url = "http://hydra.nixos.org/jobset/{}".format(jobset) 72 73 # get the last evaluation 74 click.echo(click.style( 75 'Getting latest evaluation for {}'.format(url), fg='green')) 76 d = get_response_text(url) 77 evaluations = d('#tabs-evaluations').find('a[class="row-link"]') 78 latest_eval_url = evaluations[0].get('href') 79 80 # parse last evaluation page 81 click.echo(click.style( 82 'Parsing evaluation {}'.format(latest_eval_url), fg='green')) 83 d = get_response_text(latest_eval_url + '?full=1') 84 85 # TODO: aborted evaluations 86 # TODO: dependency failed without propagated builds 87 print('\nFailures:') 88 for tr in d('img[alt="Failed"]').parents('tr'): 89 print_build(tr) 90 91 print('\nDependency failures:') 92 for tr in d('img[alt="Dependency failed"]').parents('tr'): 93 print_build(tr) 94 95 96if __name__ == "__main__": 97 try: 98 cli() 99 except Exception as e: 100 import pdb;pdb.post_mortem()