|
@@ -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())
|
|
|
+
|