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