forked from mirrors/nixpkgs
7b0167204d
tarballs.nixos.org is omitted from the change because urls from there are always hashed and checked
113 lines
3.1 KiB
Python
Executable file
113 lines
3.1 KiB
Python
Executable file
#!/usr/bin/env nix-shell
|
|
#!nix-shell -i python3 -p 'python3.withPackages(ps: with ps; [ requests pyquery click ])'
|
|
|
|
# To use, just execute this script with --help to display help.
|
|
|
|
import subprocess
|
|
import json
|
|
import sys
|
|
|
|
import click
|
|
import requests
|
|
from pyquery import PyQuery as pq
|
|
|
|
def map_dict (f, d):
|
|
for k,v in d.items():
|
|
d[k] = f(v)
|
|
|
|
maintainers_json = subprocess.check_output([
|
|
'nix-instantiate', '-A', 'lib.maintainers', '--eval', '--strict', '--json'
|
|
])
|
|
maintainers = json.loads(maintainers_json)
|
|
MAINTAINERS = map_dict(lambda v: v.get('github', None), maintainers)
|
|
|
|
def get_response_text(url):
|
|
return pq(requests.get(url).text) # IO
|
|
|
|
EVAL_FILE = {
|
|
'nixos': 'nixos/release.nix',
|
|
'nixpkgs': 'pkgs/top-level/release.nix',
|
|
}
|
|
|
|
|
|
def get_maintainers(attr_name):
|
|
try:
|
|
nixname = attr_name.split('.')
|
|
meta_json = subprocess.check_output([
|
|
'nix-instantiate',
|
|
'--eval',
|
|
'--strict',
|
|
'-A',
|
|
'.'.join(nixname[1:]) + '.meta',
|
|
EVAL_FILE[nixname[0]],
|
|
'--arg',
|
|
'nixpkgs',
|
|
'./.',
|
|
'--json'])
|
|
meta = json.loads(meta_json)
|
|
return meta.get('maintainers', [])
|
|
except:
|
|
return []
|
|
|
|
def filter_github_users(maintainers):
|
|
github_only = []
|
|
for i in maintainers:
|
|
if i.get('github'):
|
|
github_only.append(i)
|
|
return github_only
|
|
|
|
def print_build(table_row):
|
|
a = pq(table_row)('a')[1]
|
|
print("- [ ] [{}]({})".format(a.text, a.get('href')), flush=True)
|
|
|
|
job_maintainers = filter_github_users(get_maintainers(a.text))
|
|
if job_maintainers:
|
|
print(" - maintainers: {}".format(" ".join(map(lambda u: '@' + u.get('github'), job_maintainers))))
|
|
# TODO: print last three persons that touched this file
|
|
# TODO: pinpoint the diff that broke this build, or maybe it's transient or maybe it never worked?
|
|
|
|
sys.stdout.flush()
|
|
|
|
@click.command()
|
|
@click.option(
|
|
'--jobset',
|
|
default="nixos/release-19.09",
|
|
help='Hydra project like nixos/release-19.09')
|
|
def cli(jobset):
|
|
"""
|
|
Given a Hydra project, inspect latest evaluation
|
|
and print a summary of failed builds
|
|
"""
|
|
|
|
url = "https://hydra.nixos.org/jobset/{}".format(jobset)
|
|
|
|
# get the last evaluation
|
|
click.echo(click.style(
|
|
'Getting latest evaluation for {}'.format(url), fg='green'))
|
|
d = get_response_text(url)
|
|
evaluations = d('#tabs-evaluations').find('a[class="row-link"]')
|
|
latest_eval_url = evaluations[0].get('href')
|
|
|
|
# parse last evaluation page
|
|
click.echo(click.style(
|
|
'Parsing evaluation {}'.format(latest_eval_url), fg='green'))
|
|
d = get_response_text(latest_eval_url + '?full=1')
|
|
|
|
# TODO: aborted evaluations
|
|
# TODO: dependency failed without propagated builds
|
|
print('\nFailures:')
|
|
for tr in d('img[alt="Failed"]').parents('tr'):
|
|
print_build(tr)
|
|
|
|
print('\nDependency failures:')
|
|
for tr in d('img[alt="Dependency failed"]').parents('tr'):
|
|
print_build(tr)
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
cli()
|
|
except Exception as e:
|
|
import pdb;pdb.post_mortem()
|