forked from canonical/snapd
-
Notifications
You must be signed in to change notification settings - Fork 1
/
check-pr-title.py
executable file
·78 lines (63 loc) · 2.33 KB
/
check-pr-title.py
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
#!/usr/bin/python3
import argparse
import re
import urllib.request
from html.parser import HTMLParser
class InvalidPRTitle(Exception):
def __init__(self, invalid_title):
self.invalid_title = invalid_title
class GithubTitleParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self._cur_tag = ""
self.title = ""
def handle_starttag(self, tag, attributes):
self._cur_tag = tag
def handle_endtag(self, tag):
self._cur_tag = ""
def handle_data(self, data):
if self._cur_tag == "title":
self.title = data
def check_pr_title(pr_number: int):
# ideally we would use the github API - however we can't because:
# a) its rate limiting and travis IPs hit the API a lot so we regularly
# get errors
# b) using a API token is tricky because travis will not allow the secure
# vars for forks
# so instead we just scrape the html title which is unlikely to change
# radically
parser = GithubTitleParser()
with urllib.request.urlopen(
"https://github.com/snapcore/snapd/pull/{}".format(pr_number)
) as f:
parser.feed(f.read().decode("utf-8"))
# the title has the format:
# "Added api endpoint for downloading snaps by glower · Pull Request #6958 · snapcore/snapd · GitHub"
# so we rsplit() once to get the title (rsplit to not get confused by
# possible "by" words in the real title)
title = parser.title.rsplit(" by ", maxsplit=1)[0]
print(title)
# cover most common cases:
# package: foo
# package, otherpackage/subpackage: this is a title
# tests/regression/lp-12341234: foo
# [RFC] foo: bar
if not re.match(r"[a-zA-Z0-9_\-\*/,. \[\]{}]+: .*", title):
raise InvalidPRTitle(title)
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"pr_number", metavar="PR number", help="the github PR number to check"
)
args = parser.parse_args()
try:
check_pr_title(args.pr_number)
except InvalidPRTitle as e:
print('Invalid PR title: "{}"\n'.format(e.invalid_title))
print("Please provide a title in the following format:")
print("module: short description")
print("E.g.:")
print("daemon: fix frobinator bug")
raise SystemExit(1)
if __name__ == "__main__":
main()