Files
snapd/check-commit-email.py

67 lines
2.4 KiB
Python
Raw Permalink Normal View History

#!/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))
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 == "":
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)