Skip to content

Commit

Permalink
contrib/git-hooks: add a sendemail-validate example hook that adds FR…
Browse files Browse the repository at this point in the history
…OM: lines to outgoing patch emails

This is useful for people using Microsoft Exchange / Office 360, which
butchers patches causing author identity to be lost.

(From OE-Core rev: 8dc690fddc1bace6b7af3f5e8af60c1625b067db)

Signed-off-by: Chris Laplante <[email protected]>
Signed-off-by: Richard Purdie <[email protected]>
  • Loading branch information
chris-laplante authored and rpurdie committed Dec 30, 2020
1 parent 2421a2c commit 53afafe
Showing 1 changed file with 78 additions and 0 deletions.
78 changes: 78 additions & 0 deletions contrib/git-hooks/sendemail-validate.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env python3

# Copyright (C) 2020 Agilent Technologies, Inc.
# Author: Chris Laplante <[email protected]>

# This sendemail-validate hook injects 'From: ' header lines into outgoing
# emails sent via 'git send-email', to ensure that accurate commit authorship
# information is present. It was created because some email servers
# (notably Microsoft Exchange / Office 360) seem to butcher outgoing patches,
# resulting in incorrect authorship.

# Current limitations:
# 1. Assumes one per patch per email
# 2. Minimal error checking
#
# Installation:
# 1. Copy to .git/hooks/sendemail-validate
# 2. chmod +x .git/hooks/sendemail-validate


import enum
import re
import subprocess
import sys


class Subject(enum.IntEnum):
NOT_SEEN = 0
CONSUMING = 1
SEEN = 2


def make_from_line():
cmd = ["git", "var", "GIT_COMMITTER_IDENT"]
proc = subprocess.run(cmd, check=True, stdout=subprocess.PIPE, universal_newlines=True)
regex = re.compile(r"^(.*>).*$")
match = regex.match(proc.stdout)
assert match is not None
return "From: {0}".format(match.group(1))


def main():
email = sys.argv[1]

with open(email, "r") as f:
email_lines = f.read().split("\n")

subject_seen = Subject.NOT_SEEN
first_body_line = None
for i, line in enumerate(email_lines):
if (subject_seen == Subject.NOT_SEEN) and line.startswith("Subject: "):
subject_seen = Subject.CONSUMING
continue
if subject_seen == Subject.CONSUMING:
if not line.strip():
subject_seen = Subject.SEEN
continue
if subject_seen == Subject.SEEN:
first_body_line = i
break

assert subject_seen == Subject.SEEN
assert first_body_line is not None

from_line = make_from_line()
# Only add FROM line if it is not already there
if email_lines[first_body_line] != from_line:
email_lines.insert(first_body_line, from_line)
email_lines.insert(first_body_line + 1, "")
with open(email, "w") as f:
f.write("\n".join(email_lines))

return 0


if __name__ == "__main__":
sys.exit(main())

0 comments on commit 53afafe

Please sign in to comment.