-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy pathinactive_utils.py
More file actions
166 lines (138 loc) · 5.57 KB
/
inactive_utils.py
File metadata and controls
166 lines (138 loc) · 5.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
from bugbot import utils
def process_bugs(bugs, get_revisions_fn, needinfo_func):
rev_ids = {rev_id for bug in bugs.values() for rev_id in bug["rev_ids"]}
revisions = get_revisions_fn(list(rev_ids))
for bugid, bug in list(bugs.items()):
inactive_revs = [
revisions[rev_id] for rev_id in bug["rev_ids"] if rev_id in revisions
]
if inactive_revs:
bug["revisions"] = inactive_revs
needinfo_user = needinfo_func(bugid, inactive_revs)
bug["needinfo_user"] = needinfo_user
else:
del bugs[bugid]
# Resolving https://github.com/mozilla/bugbot/issues/1300 should clean this
# including improve the wording in the template (i.e., "See the search query on Bugzilla").
query_url = utils.get_bz_search_url({"bug_id": ",".join(bugs.keys())})
return bugs, query_url
def handle_bug_util(bug, data, PHAB_FILE_NAME_PAT, PHAB_TABLE_PAT, bot):
rev_ids = [
# To avoid loading the attachment content (which can be very large),
# we extract the revision id from the file name, which is in the
# format of "phabricator-D{revision_id}-url.txt".
# len("phabricator-D") == 13
# len("-url.txt") == 8
int(attachment["file_name"][13:-8])
for attachment in bug["attachments"]
if attachment["content_type"] == "text/x-phabricator-request"
and PHAB_FILE_NAME_PAT.match(attachment["file_name"])
and not attachment["is_obsolete"]
]
if not rev_ids:
return
# We should not comment about the same patch more than once.
rev_ids_with_ni = set()
for comment in bug["comments"]:
if comment["creator"] == bot and comment["raw_text"].startswith(
"The following patch"
):
rev_ids_with_ni.update(
int(id) for id in PHAB_TABLE_PAT.findall(comment["raw_text"])
)
if rev_ids_with_ni:
rev_ids = [id for id in rev_ids if id not in rev_ids_with_ni]
if not rev_ids:
return
# It will be nicer to show a sorted list of patches
rev_ids.sort()
bugid = str(bug["id"])
data[bugid] = {
"rev_ids": rev_ids,
}
return bug
def get_revisions(
revs,
fetch_revs_func,
get_phab_users_with_status_func,
status_note_func,
user_status_active,
):
revisions = []
for _rev_ids in revs:
for revision in fetch_revs_func(_rev_ids):
if (
len(revision["attachments"]["reviewers"]["reviewers"]) == 0
or revision["fields"]["status"]["value"] != "needs-review"
or revision["fields"]["isDraft"]
):
continue
reviewers = [
{
"phid": reviewer["reviewerPHID"],
"is_group": reviewer["reviewerPHID"].startswith("PHID-PROJ"),
"is_blocking": reviewer["isBlocking"],
"is_accepted": reviewer["status"] == "accepted",
"is_resigned": reviewer["status"] == "resigned",
}
for reviewer in revision["attachments"]["reviewers"]["reviewers"]
]
# Group reviewers will be consider always active; so if there is
# no other reviewers blocking, we don't need to check further.
if any(
reviewer["is_group"] or reviewer["is_accepted"]
for reviewer in reviewers
) and not any(
not reviewer["is_accepted"]
for reviewer in reviewers
if reviewer["is_blocking"]
):
continue
revisions.append(
{
"rev_id": revision["id"],
"title": revision["fields"]["title"],
"created_at": revision["fields"]["dateCreated"],
"author_phid": revision["fields"]["authorPHID"],
"reviewers": reviewers,
}
)
user_phids = set()
for revision in revisions:
user_phids.add(revision["author_phid"])
for reviewer in revision["reviewers"]:
user_phids.add(reviewer["phid"])
users = get_phab_users_with_status_func(list(user_phids), keep_active=True)
result = {}
for revision in revisions:
# It is not useful to notify an inactive author about an inactive
# reviewer, thus we should exclude revisions with inactive authors.
author_info = users[revision["author_phid"]]
if author_info["status"] != user_status_active:
continue
revision["author"] = author_info
inactive_reviewers = []
for reviewer in revision["reviewers"]:
if reviewer["is_group"]:
continue
reviewer_info = users[reviewer["phid"]]
if (
not reviewer["is_resigned"]
and reviewer_info["status"] == user_status_active
):
continue
reviewer["info"] = reviewer_info
inactive_reviewers.append(reviewer)
if len(inactive_reviewers) == len(revision["reviewers"]) or any(
reviewer["is_blocking"] and not reviewer["is_accepted"]
for reviewer in inactive_reviewers
):
revision["reviewers"] = [
{
"phab_username": reviewer["info"]["phab_username"],
"status_note": status_note_func(reviewer),
}
for reviewer in inactive_reviewers
]
result[revision["rev_id"]] = revision
return result