]> git.lizzy.rs Git - rust.git/blob - src/tools/publish_toolstate.py
Provides direct link to the PR when toolstate is changed.
[rust.git] / src / tools / publish_toolstate.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 # Copyright 2017 The Rust Project Developers. See the COPYRIGHT
5 # file at the top-level directory of this distribution and at
6 # http://rust-lang.org/COPYRIGHT.
7 #
8 # Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
9 # http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
10 # <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
11 # option. This file may not be copied, modified, or distributed
12 # except according to those terms.
13
14 import sys
15 import re
16 import json
17 import copy
18 import datetime
19 import collections
20 import textwrap
21
22 # List of people to ping when the status of a tool changed.
23 MAINTAINERS = {
24     'miri': '@oli-obk @RalfJung @eddyb',
25     'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk',
26     'rls': '@nrc',
27     'rustfmt': '@nrc',
28 }
29
30
31 def read_current_status(current_commit, path):
32     '''Reads build status of `current_commit` from content of `history/*.tsv`
33     '''
34     with open(path, 'rU') as f:
35         for line in f:
36             (commit, status) = line.split('\t', 1)
37             if commit == current_commit:
38                 return json.loads(status)
39     return {}
40
41
42 def update_latest(
43     current_commit,
44     relevant_pr_number,
45     relevant_pr_url,
46     current_datetime
47 ):
48     '''Updates `_data/latest.json` to match build result of the given commit.
49     '''
50     with open('_data/latest.json', 'rb+') as f:
51         latest = json.load(f, object_pairs_hook=collections.OrderedDict)
52
53         current_status = {
54             os: read_current_status(current_commit, 'history/' + os + '.tsv')
55             for os in ['windows', 'linux']
56         }
57
58         slug = 'rust-lang/rust'
59         message = textwrap.dedent('''\
60             ðŸ“£ Toolstate changed by {}!
61
62             Tested on commit {}@{}.
63             Direct link to PR: <{}>
64
65         ''').format(relevant_pr_number, slug, current_commit, relevant_pr_url)
66         anything_changed = False
67         for status in latest:
68             tool = status['tool']
69             changed = False
70
71             for os, s in current_status.items():
72                 old = status[os]
73                 new = s.get(tool, old)
74                 status[os] = new
75                 if new > old:
76                     changed = True
77                     message += '🎉 {} on {}: {} â†’ {}.\n' \
78                         .format(tool, os, old, new)
79                 elif new < old:
80                     changed = True
81                     message += '💔 {} on {}: {} â†’ {} (cc {}).\n' \
82                         .format(tool, os, old, new, MAINTAINERS[tool])
83
84             if changed:
85                 status['commit'] = current_commit
86                 status['datetime'] = current_datetime
87                 anything_changed = True
88
89         if not anything_changed:
90             return ''
91
92         f.seek(0)
93         f.truncate(0)
94         json.dump(latest, f, indent=4, separators=(',', ': '))
95         return message
96
97
98 if __name__ == '__main__':
99     cur_commit = sys.argv[1]
100     cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
101     cur_commit_msg = sys.argv[2]
102     save_message_to_path = sys.argv[3]
103
104     relevant_pr_match = re.search('#([0-9]+)', cur_commit_msg)
105     if relevant_pr_match:
106         number = relevant_pr_match.group(1)
107         relevant_pr_number = 'rust-lang/rust#' + number
108         relevant_pr_url = 'https://github.com/rust-lang/rust/pull/' + number
109     else:
110         relevant_pr_number = '<unknown PR>'
111         relevant_pr_url = '<unknown>'
112
113     message = update_latest(
114         cur_commit,
115         relevant_pr_number,
116         relevant_pr_url,
117         cur_datetime
118     )
119     if message:
120         print(message)
121         with open(save_message_to_path, 'w') as f:
122             f.write(message)
123     else:
124         print('<Nothing changed>')