lts/lts-release-mail.py: Script to generate LTS release email

Based on specification in
https://linaro.atlassian.net/browse/TFC-471

In addition to the spec, implemented --latest option to use the latest
release tag.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
Change-Id: Ied82a6b5d744ffa539e0916fa2b152a8cd5b4a1d
diff --git a/lts/lts-release-mail.py b/lts/lts-release-mail.py
new file mode 100755
index 0000000..1b7e048
--- /dev/null
+++ b/lts/lts-release-mail.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python3
+import argparse
+import sys
+import os
+import re
+import subprocess
+
+
+WORKDIR = "trusted-firmware-a"
+
+
+def run(cmd):
+    return subprocess.check_call(cmd, shell=True)
+
+
+def maybe_int(s):
+    if s.isdigit():
+        return int(s)
+    return s
+
+
+def main():
+    argp = argparse.ArgumentParser(description="Prepare TF-A LTS release email content")
+    argp.add_argument("--latest", action="store_true", help="use latest release tag")
+    argp.add_argument("release_tag", nargs="?", help="release tag")
+    args = argp.parse_args()
+    if not args.release_tag and not args.latest:
+        argp.error("Either release_tag or --latest is required")
+
+    with open(os.path.dirname(__file__) + "/lts-release-mail.txt") as f:
+        mail_template = f.read()
+
+    if not os.path.exists(WORKDIR):
+        run("git clone https://review.trustedfirmware.org/TF-A/trusted-firmware-a %s" % WORKDIR)
+        os.chdir(WORKDIR)
+    else:
+        os.chdir(WORKDIR)
+        run("git pull --quiet")
+
+    if args.latest:
+        latest = []
+        for l in os.popen("git tag"):
+            if not re.match(r"lts-v\d+\.\d+\.\d+", l):
+                continue
+            l = l.rstrip()
+            comps = [maybe_int(x) for x in l.split(".")]
+            comps.append(l)
+            if comps > latest:
+                latest = comps
+        if not latest:
+            argp.error("Could not find latest LTS tag")
+        args.release_tag = latest[-1]
+
+    comps = args.release_tag.split(".")
+    prev_comps = comps[:-1] + [str(int(comps[-1]) - 1)]
+    prev_release = ".".join(prev_comps)
+
+    subjects = []
+    for l in os.popen("git log --oneline --reverse %s..%s" % (prev_release, args.release_tag)):
+        subjects.append(l.rstrip())
+    subjects = subjects[:-3]
+
+    urls = []
+    for s in subjects:
+        commit_id, _ = s.split(" ", 1)
+        for l in os.popen("git show %s" % commit_id):
+            if "Change-Id:" in l:
+                _, change_id = l.strip().split(None, 1)
+                urls.append("https://review.trustedfirmware.org/q/" + change_id)
+
+    assert len(subjects) == len(urls)
+
+    commits = ""
+    for i, s in enumerate(subjects, 1):
+        commits += "%s [%d]\n" % (s, i)
+
+    references = ""
+    for i, s in enumerate(urls, 1):
+        references += "[%d] %s\n" % (i, s)
+
+    # Strip trailing newline, as it's encoded in template.
+    commits = commits.rstrip()
+    references = references.rstrip()
+
+    version = args.release_tag[len("lts-v"):]
+    sys.stdout.write(
+        mail_template.format(
+            version=version,
+            commits=commits,
+            references=references,
+        )
+    )
+
+
+if __name__ == "__main__":
+    main()