1 #!/usr/bin/env nix-shell
2 #!nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ requests pyquery click ])"
4 # To use, just execute this script with --help to display help.
12 from pyquery
import PyQuery
as pq
18 maintainers_json
= subprocess
.check_output([
19 'nix-instantiate', '-A', 'lib.maintainers', '--eval', '--strict', '--json'
21 maintainers
= json
.loads(maintainers_json
)
22 MAINTAINERS
= map_dict(lambda v
: v
.get('github', None), maintainers
)
24 def get_response_text(url
):
25 return pq(requests
.get(url
).text
) # IO
28 'nixos': 'nixos/release.nix',
29 'nixpkgs': 'pkgs/top-level/release.nix',
33 def get_maintainers(attr_name
):
35 nixname
= attr_name
.split('.')
36 meta_json
= subprocess
.check_output([
41 '.'.join(nixname
[1:]) + '.meta',
42 EVAL_FILE
[nixname
[0]],
47 meta
= json
.loads(meta_json
)
48 return meta
.get('maintainers', [])
52 def filter_github_users(maintainers
):
59 def print_build(table_row
):
60 a
= pq(table_row
)('a')[1]
61 print("- [ ] [{}]({})".format(a
.text
, a
.get('href')), flush
=True)
63 job_maintainers
= filter_github_users(get_maintainers(a
.text
))
65 print(" - maintainers: {}".format(" ".join(map(lambda u
: '@' + u
.get('github'), job_maintainers
))))
66 # TODO: print last three persons that touched this file
67 # TODO: pinpoint the diff that broke this build, or maybe it's transient or maybe it never worked?
74 default
="nixos/release-19.09",
75 help='Hydra project like nixos/release-19.09')
78 Given a Hydra project, inspect latest evaluation
79 and print a summary of failed builds
82 url
= "https://hydra.nixos.org/jobset/{}".format(jobset
)
84 # get the last evaluation
85 click
.echo(click
.style(
86 'Getting latest evaluation for {}'.format(url
), fg
='green'))
87 d
= get_response_text(url
)
88 evaluations
= d('#tabs-evaluations').find('a[class="row-link"]')
89 latest_eval_url
= evaluations
[0].get('href')
91 # parse last evaluation page
92 click
.echo(click
.style(
93 'Parsing evaluation {}'.format(latest_eval_url
), fg
='green'))
94 d
= get_response_text(latest_eval_url
+ '?full=1')
96 # TODO: aborted evaluations
97 # TODO: dependency failed without propagated builds
99 for tr
in d('img[alt="Failed"]').parents('tr'):
102 print('\nDependency failures:')
103 for tr
in d('img[alt="Dependency failed"]').parents('tr'):
108 if __name__
== "__main__":
111 except Exception as e
:
112 import pdb
;pdb
.post_mortem()