at 18.03-beta 95 lines 2.7 kB view raw
1#!/usr/bin/env nix-shell 2#!nix-shell -i python -p pythonFull pythonPackages.requests pythonPackages.pyquery pythonPackages.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 ./lib/maintainers.nix {}', '--eval', '--json' 17]) 18maintainers = json.loads(maintainers_json) 19MAINTAINERS = {v: k for k, v in maintainers.iteritems()} 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 48 49@click.command() 50@click.option( 51 '--jobset', 52 default="nixos/release-17.09", 53 help='Hydra project like nixos/release-17.09') 54def cli(jobset): 55 """ 56 Given a Hydra project, inspect latest evaluation 57 and print a summary of failed builds 58 """ 59 60 url = "http://hydra.nixos.org/jobset/{}".format(jobset) 61 62 # get the last evaluation 63 click.echo(click.style( 64 'Getting latest evaluation for {}'.format(url), fg='green')) 65 d = get_response_text(url) 66 evaluations = d('#tabs-evaluations').find('a[class="row-link"]') 67 latest_eval_url = evaluations[0].get('href') 68 69 # parse last evaluation page 70 click.echo(click.style( 71 'Parsing evaluation {}'.format(latest_eval_url), fg='green')) 72 d = get_response_text(latest_eval_url + '?full=1') 73 74 # TODO: aborted evaluations 75 # TODO: dependency failed without propagated builds 76 for tr in d('img[alt="Failed"]').parents('tr'): 77 a = pq(tr)('a')[1] 78 print("- [ ] [{}]({})".format(a.text, a.get('href'))) 79 80 sys.stdout.flush() 81 82 maintainers = get_maintainers(a.text) 83 if maintainers: 84 print(" - maintainers: {}".format(", ".join(map(lambda u: '@' + u, maintainers)))) 85 # TODO: print last three persons that touched this file 86 # TODO: pinpoint the diff that broke this build, or maybe it's transient or maybe it never worked? 87 88 sys.stdout.flush() 89 90 91if __name__ == "__main__": 92 try: 93 cli() 94 except: 95 import pdb;pdb.post_mortem()