Warning, /sdk/kde-dev-scripts/reviewboard-am is written in an unsupported language. File is not indexed.

0001 #!/usr/bin/env python
0002 # encoding: utf-8
0003 
0004 """
0005 Copyright 2013 Aurélien Gâteau <agateau@kde.org>
0006 
0007 Redistribution and use in source and binary forms, with or without modification,
0008 are permitted provided that the following conditions are met:
0009 
0010 1. Redistributions of source code must retain the above copyright notice, this
0011    list of conditions and the following disclaimer.
0012 
0013 2. Redistributions in binary form must reproduce the above copyright notice,
0014    this list of conditions and the following disclaimer in the documentation
0015    and/or other materials provided with the distribution.
0016 
0017 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS OR
0018 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
0020 SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
0021 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0022 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0023 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0024 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
0025 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
0026 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0027 
0028 The views and conclusions contained in the software and documentation are those
0029 of the authors and should not be interpreted as representing official policies,
0030 either expressed or implied, of the copyright holders.
0031 """
0032 
0033 from __future__ import print_function
0034 
0035 import sys
0036 import json
0037 import os
0038 import subprocess
0039 try:
0040     from urllib.request import urlopen
0041     from urllib.error import HTTPError
0042 except ImportError:
0043     from urllib2 import urlopen, HTTPError
0044     input = raw_input
0045 
0046 from argparse import ArgumentParser
0047 
0048 RB_URL = "https://git.reviewboard.kde.org"
0049 
0050 DEBUG_JSON = "DEBUG_JSON" in os.environ
0051 
0052 def retrieve_text(url):
0053     data = urlopen(url).read()
0054     if type(data) != str:
0055         data = data.decode('utf8')
0056     return data
0057 
0058 
0059 def api_request(url):
0060     if DEBUG_JSON:
0061         print("DEBUG_JSON: Fetching", url)
0062     data = retrieve_text(url)
0063     dct = json.loads(data)
0064     if DEBUG_JSON:
0065         print("DEBUG_JSON:")
0066         print(json.dumps(dct, sort_keys=True, indent=4))
0067     return dct
0068 
0069 
0070 def git(*args):
0071     cmd = ["git"] + list(args)
0072     print("Running '%s'" % " ".join(cmd))
0073     return subprocess.call(cmd) == 0
0074 
0075 
0076 class RBClientError(Exception):
0077     pass
0078 
0079 
0080 class RBClient(object):
0081     def __init__(self, url):
0082         self.url = url
0083 
0084     def get_request_info(self, request_id):
0085         try:
0086             dct = api_request(self.url + "/api/review-requests/%d/" % request_id)
0087         except HTTPError as exc:
0088             if exc.code == 404:
0089                 raise RBClientError("HTTP Error 404: there is probably no request with id %d." % request_id)
0090             raise
0091 
0092         return dct["review_request"]
0093 
0094     def get_author_info(self, submitter_url):
0095         dct = api_request(submitter_url)
0096         return dct["user"]
0097 
0098     def download_diff(self, request_id):
0099         return retrieve_text(self.url + "/r/%d/diff/raw/" % request_id)
0100 
0101 
0102 def parse_author_info(author_info):
0103     def loop_raw_input(prompt):
0104         while True:
0105             out = input(prompt)
0106             if out:
0107                 return out
0108             print("Invalid value.")
0109 
0110     fullname = author_info.get("fullname")
0111     email = author_info.get("email")
0112     username = author_info["username"]
0113     if fullname is None:
0114         fullname = loop_raw_input("Could not get fullname for user '%s'. Please enter it: " % username)
0115     if email is None:
0116         email = loop_raw_input("Could not get email for user '%s'. Please enter it: " % username)
0117     return fullname, email
0118 
0119 
0120 def write_patch(fl, fullname, email, summary, description, diff):
0121     author = "%s <%s>" % (fullname, email)
0122     print("From:", author, file=fl)
0123     print("Subject:", summary, file=fl)
0124     print(file=fl)
0125     print(description, file=fl)
0126     print("---", file=fl)
0127     print(file=fl)
0128     fl.write(diff)
0129 
0130 
0131 def detect_p_value(diff):
0132     for line in diff.splitlines():
0133         if line.startswith("diff --git a/"):
0134             return 1
0135         elif line.startswith("diff --git "):
0136             return 0
0137     return 1
0138 
0139 
0140 def main():
0141     parser = ArgumentParser()
0142     parser.add_argument("request_id", type=int,
0143                         help="reviewboard ID to apply")
0144     parser.add_argument("-b", "--branch",
0145                         action="store_true", dest="branch", default=False,
0146                         help="create a branch named after the reviewboard ID")
0147     args = parser.parse_args()
0148 
0149     request_id = args.request_id
0150 
0151     rb = RBClient(RB_URL)
0152 
0153     print("Fetching request info")
0154     try:
0155         request_info = rb.get_request_info(request_id)
0156     except RBClientError as exc:
0157         print(exc)
0158         return 1
0159     author_info = rb.get_author_info(request_info["links"]["submitter"]["href"])
0160     summary = request_info["summary"]
0161     description = request_info["description"]
0162     description += "\n\nREVIEW: " + str(request_id)
0163     for bug_closed in request_info["bugs_closed"]:
0164         description += "\nBUG: " + bug_closed
0165     fullname, email = parse_author_info(author_info)
0166 
0167     print("Downloading diff")
0168     diff = rb.download_diff(request_id)
0169 
0170     name = "rb-%d.patch" % request_id
0171     print("Creating %s" % name)
0172     with open(name, "w") as fl:
0173         write_patch(fl, fullname, email, summary, description, diff)
0174 
0175     if args.branch:
0176         if not git("checkout", "-b", "rb-%d" % request_id):
0177             return 1
0178 
0179     p_value = detect_p_value(diff)
0180 
0181     if not git("am", "-p%d" % p_value, name):
0182         return 1
0183 
0184     return 0
0185 
0186 if __name__ == "__main__":
0187     sys.exit(main())
0188 # vi: ts=4 sw=4 et