]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core.git/commitdiff
contrib/git-hooks: add a sendemail-validate example hook that adds FROM: lines to...
authorChris Laplante <chris.laplante@agilent.com>
Fri, 25 Dec 2020 18:16:49 +0000 (13:16 -0500)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Wed, 30 Dec 2020 13:57:17 +0000 (13:57 +0000)
This is useful for people using Microsoft Exchange / Office 360, which
butchers patches causing author identity to be lost.

Signed-off-by: Chris Laplante <chris.laplante@agilent.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
contrib/git-hooks/sendemail-validate.sample [new file with mode: 0755]

diff --git a/contrib/git-hooks/sendemail-validate.sample b/contrib/git-hooks/sendemail-validate.sample
new file mode 100755 (executable)
index 0000000..af5d55c
--- /dev/null
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2020  Agilent Technologies, Inc.
+# Author: Chris Laplante <chris.laplante@agilent.com>
+
+# 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())
+