forked from canonical/snapd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
check-commit-email.py
executable file
·74 lines (66 loc) · 2.74 KB
/
check-commit-email.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
#!/usr/bin/python3
# This script checks that the committer and author email addresses of commits
# are valid - this is important because we need to be able to import the git
# repo to launchpad and launchpad does not like git commits that are formatted
# badly.
# This can be run either on a merge commit in which case the commits it
# evaluates is just limited to the "other" branch (the one being merged into the
# destination) like we do in CI workflows. Or it can be run on a normal commit
# like a developer would do locally in which case this ends up checking all
# commits locally - some day that may grow to be unwieldy but for now seems ok.
import os
import subprocess
from email.utils import parseaddr
def get_commit_range():
# For CI, the head revision is a synthesised merge commit,
# merging the proposed branch into the destination branch.
# So the first parent is our destination, and the second is
# our proposal.
lines = subprocess.check_output(
["git", "cat-file", "-p", "@"], text=True
).splitlines()
parents = [
line[len("parent ") :].strip() for line in lines if line.startswith("parent ")
]
if len(parents) == 1:
# not a merge commit, so return nothing to use default git log behavior
# and check all commits
return ""
elif len(parents) == 2:
# merge commit so use "foo..bar" syntax to just check the proposed
# commits
dest, proposed = parents
return "{}..{}".format(dest, proposed)
else:
raise RuntimeError("expected two parents, but got {}".format(parents))
def exception_invalid(maybeaddr: str) -> bool:
# from commit d935048f4ee5f9a8cde640a760bf1fdb9409de7e
# dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
if "+dependabot[bot]@users.noreply.github.com" in maybeaddr:
return True
return False
if __name__ == "__main__":
if not os.path.exists('.git'):
exit(0)
commitrange = get_commit_range()
args = ["git", "log", "--format=format:%h,%ce%n%h,%ae"]
if commitrange != "":
args.append(commitrange)
for line in subprocess.check_output(args, text=True).split("\n"):
parsed = line.split(",", 1)
commithash = parsed[0]
potentialemail = parsed[1]
if potentialemail == "":
continue
name, addr = parseaddr(potentialemail)
if addr == "" and not exception_invalid(potentialemail):
print(
"Found invalid email %s for commmit %s" % (potentialemail, commithash)
)
exit(1)
if not addr.isascii():
print(
"Found invalid non-ascii email %s for commmit %s"
% (potentialemail, commithash)
)
exit(1)