Files
snapd/check-commit-email.py
Maciej Borzecki 7ec49c006d check-commit-email: do not fail when current dir is not under git
The check fails with a source tarball, like the one used during spread tests.

```
Error: 2022-01-21 07:44:44 Error executing google:ubuntu-20.04-64:tests/unit/go (jan210735-282406) :
-----
...
Obtaining c-dependencies
HEAD is now at 74f4fe8 Merge pull request #63 from vasi/vasi-win-ci
Checking docs
fatal: not a git repository (or any of the parent directories): .git
Traceback (most recent call last):
  File "./check-commit-email.py", line 42, in <module>
    commitrange = get_commit_range()
  File "./check-commit-email.py", line 22, in get_commit_range
    lines = subprocess.check_output(
  File "/usr/lib/python3.8/subprocess.py", line 415, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  File "/usr/lib/python3.8/subprocess.py", line 516, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['git', 'cat-file', '-p', '@']' returned non-zero exit status 128.

Crushing failure and despair.
```

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
2022-01-21 11:25:48 +01:00

67 lines
2.4 KiB
Python
Executable File

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