| #!/usr/bin/env python | 
 | # Copyright (C) 2017 The Android Open Source Project | 
 | # | 
 | # Licensed under the Apache License, Version 2.0 (the "License"); | 
 | # you may not use this file except in compliance with the License. | 
 | # You may obtain a copy of the License at | 
 | # | 
 | # http://www.apache.org/licenses/LICENSE-2.0 | 
 | # | 
 | # Unless required by applicable law or agreed to in writing, software | 
 | # distributed under the License is distributed on an "AS IS" BASIS, | 
 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | # See the License for the specific language governing permissions and | 
 | # limitations under the License. | 
 |  | 
 | # Generates the text to paste into the email for announcing a new | 
 | # release of Gerrit. The text is generated based on a template that | 
 | # is filled with values either passed to the script or calculated | 
 | # at runtime. | 
 | # | 
 | # The script outputs a plain text file with the announcement text: | 
 | # | 
 | #   release-announcement-gerrit-X.Y.txt | 
 | # | 
 | # and, if GPG is available, the announcement text wrapped with a | 
 | # signature: | 
 | # | 
 | #   release-announcement-gerrit-X.Y.txt.asc | 
 | # | 
 | # Usage: | 
 | # | 
 | #   ./tools/release-announcement.py -v 2.14.2 -p 2.14.1 \ | 
 | #      -s "This release fixes several bugs since 2.14.1" | 
 | # | 
 | # Parameters: | 
 | # | 
 | #   --version (-v): The version of Gerrit being released. | 
 | # | 
 | #   --previous (-p): The previous version of Gerrit.  Optional. If | 
 | #   specified, the generated text includes a link to the gitiles | 
 | #   log of commits between the previous and new versions. | 
 | # | 
 | #   --summary (-s): Short summary of the release. Optional. When | 
 | #   specified, the summary is inserted in the introductory sentence | 
 | #   of the generated text. | 
 | # | 
 | # Prerequisites: | 
 | # | 
 | # - The Jinja2 python library [1] must be installed. | 
 | # | 
 | # - For GPG signing to work, the python-gnupg library [2] must be | 
 | #   installed, and the ~/.gnupg folder must exist. | 
 | # | 
 | # - The war file must have been installed to the local Maven repository | 
 | #   using the `./tools/mvn/api.sh war_install` command. | 
 | # | 
 | # [1] http://jinja.pocoo.org/ | 
 | # [2] http://pythonhosted.org/gnupg/ | 
 |  | 
 |  | 
 | from __future__ import print_function | 
 | import argparse | 
 | import hashlib | 
 | import os | 
 | import sys | 
 | from gnupg import GPG | 
 | from jinja2 import Template | 
 |  | 
 |  | 
 | class Version: | 
 |     def __init__(self, version): | 
 |         self.version = version | 
 |         parts = version.split('.') | 
 |         if len(parts) > 2: | 
 |             self.major = ".".join(parts[:2]) | 
 |             self.patch = version | 
 |         else: | 
 |             self.major = version | 
 |             self.patch = None | 
 |  | 
 |     def __str__(self): | 
 |         return self.version | 
 |  | 
 |  | 
 | def _main(): | 
 |     descr = 'Generate Gerrit release announcement email text' | 
 |     parser = argparse.ArgumentParser( | 
 |         description=descr, | 
 |         formatter_class=argparse.ArgumentDefaultsHelpFormatter) | 
 |     parser.add_argument('-v', '--version', dest='version', | 
 |                         required=True, | 
 |                         help='gerrit version to release') | 
 |     parser.add_argument('-p', '--previous', dest='previous', | 
 |                         help='previous gerrit version (optional)') | 
 |     parser.add_argument('-s', '--summary', dest='summary', | 
 |                         help='summary of the release content (optional)') | 
 |     options = parser.parse_args() | 
 |  | 
 |     summary = options.summary | 
 |     if summary and not summary.endswith("."): | 
 |         summary = summary + "." | 
 |  | 
 |     data = { | 
 |          "version": Version(options.version), | 
 |          "previous": options.previous, | 
 |          "summary": summary | 
 |     } | 
 |  | 
 |     war = os.path.join( | 
 |         os.path.expanduser("~/.m2/repository/com/google/gerrit/gerrit-war/"), | 
 |         "%(version)s/gerrit-war-%(version)s.war" % data) | 
 |     if not os.path.isfile(war): | 
 |         print("Could not find war file for Gerrit %s in local Maven repository" | 
 |               % data["version"], file=sys.stderr) | 
 |         sys.exit(1) | 
 |  | 
 |     md5 = hashlib.md5() | 
 |     sha1 = hashlib.sha1() | 
 |     sha256 = hashlib.sha256() | 
 |     BUF_SIZE = 65536  # Read data in 64kb chunks | 
 |     with open(war, 'rb') as f: | 
 |         while True: | 
 |             d = f.read(BUF_SIZE) | 
 |             if not d: | 
 |                 break | 
 |             md5.update(d) | 
 |             sha1.update(d) | 
 |             sha256.update(d) | 
 |  | 
 |     data["sha1"] = sha1.hexdigest() | 
 |     data["sha256"] = sha256.hexdigest() | 
 |     data["md5"] = md5.hexdigest() | 
 |  | 
 |     template = Template(open("tools/release-announcement-template.txt").read()) | 
 |     output = template.render(data=data) | 
 |  | 
 |     filename = "release-announcement-gerrit-%s.txt" % data["version"] | 
 |     with open(filename, "w") as f: | 
 |         f.write(output) | 
 |  | 
 |     gpghome = os.path.abspath(os.path.expanduser("~/.gnupg")) | 
 |     if not os.path.isdir(gpghome): | 
 |         print("Skipping signing due to missing gnupg home folder") | 
 |     else: | 
 |         try: | 
 |             gpg = GPG(homedir=gpghome) | 
 |         except TypeError: | 
 |             gpg = GPG(gnupghome=gpghome) | 
 |         signed = gpg.sign(output) | 
 |         filename = filename + ".asc" | 
 |         with open(filename, "w") as f: | 
 |             f.write(str(signed)) | 
 |  | 
 |  | 
 | if __name__ == "__main__": | 
 |     _main() |