diff --git a/.reviewboardrc b/.reviewboardrc deleted file mode 100644 index 5e8d67014c01d..0000000000000 --- a/.reviewboardrc +++ /dev/null @@ -1,3 +0,0 @@ -REPOSITORY = 'git://git.apache.org/kafka.git' -TARGET_GROUPS = 'kafka' -GUESS_FIELDS = True diff --git a/build.gradle b/build.gradle index 53b110cbe8186..96ba9e62f2f1f 100644 --- a/build.gradle +++ b/build.gradle @@ -75,8 +75,7 @@ if (new File('.git').exists()) { 'CONTRIBUTING.md', 'gradlew', 'gradlew.bat', - '**/README.md', - '.reviewboardrc' + '**/README.md' ]) } } diff --git a/dev-utils/test-patch.py b/dev-utils/test-patch.py deleted file mode 100644 index 66ec79f8f2dab..0000000000000 --- a/dev-utils/test-patch.py +++ /dev/null @@ -1,466 +0,0 @@ -#!/usr/bin/env python -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# - -# -# Pre Commit Hook for running tests and updating JIRA -# -# Original version was copied from SQOOP project. -# -import sys, os, re, urllib2, base64, subprocess, tempfile, shutil -import json -import datetime -from optparse import OptionParser - -tmp_dir = None -BASE_JIRA_URL = 'https://issues.apache.org/jira' -BRANCHES = ["trunk", "0.7", "0.7.0", "0.7.1", "0.7.2", "0.8", "0.8.1", "0.8.2"] - -# Write output to file -def write_file(filename, content): - with open(filename, "w") as text_file: - text_file.write(content) - -# Guess branch for given versions -# -# Return None if detects that JIRA belongs to more than one branch -def kafka_guess_branch(versions): - if not versions: - return BRANCHES[0] - - for version in versions: - for branch in BRANCHES: - if version == branch: - return branch - - return BRANCHES[0] - -# Verify supported branch -def kafka_verify_branch(branch): - return branch in BRANCHES - -def execute(cmd, log=True): - if log: - print "INFO: Executing %s" % (cmd) - return subprocess.call(cmd, shell=True) - -def jenkins_link_for_jira(name, endpoint): - if "BUILD_URL" in os.environ: - return "[%s|%s%s]" % (name, os.environ['BUILD_URL'], endpoint) - else: - return name - -def jenkins_file_link_for_jira(name, file): - return jenkins_link_for_jira(name, "artifact/patch-process/%s" % file) - -def jira_request(result, url, username, password, data, headers): - request = urllib2.Request(url, data, headers) - print "INFO: URL = %s, Username = %s, data = %s, headers = %s" % (url, username, data, str(headers)) - if username and password: - base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') - request.add_header("Authorization", "Basic %s" % base64string) - return urllib2.urlopen(request) - -def jira_get_defect_html(result, defect, username, password): - url = "%s/browse/%s" % (BASE_JIRA_URL, defect) - return jira_request(result, url, username, password, None, {}).read() - -def jira_get_defect(result, defect, username, password): - url = "%s/rest/api/2/issue/%s" % (BASE_JIRA_URL, defect) - return jira_request(result, url, username, password, None, {}).read() - -def jira_generate_comment(result, branch): - body = [ "Testing file [%s|%s] against branch %s took %s." % (result.attachment.split('/')[-1] , result.attachment, branch, datetime.datetime.now() - result.start_time) ] - body += [ "" ] - if result._fatal: - result._error = [ result._fatal ] + result._error - if result._error: - count = len(result._error) - if count == 1: - body += [ "{color:red}Overall:{color} -1 due to an error" ] - else: - body += [ "{color:red}Overall:{color} -1 due to %d errors" % (count) ] - else: - body += [ "{color:green}Overall:{color} +1 all checks pass" ] - body += [ "" ] - for error in result._error: - body += [ "{color:red}ERROR:{color} %s" % (error.replace("\n", "\\n")) ] - for info in result._info: - body += [ "INFO: %s" % (info.replace("\n", "\\n")) ] - for success in result._success: - body += [ "{color:green}SUCCESS:{color} %s" % (success.replace("\n", "\\n")) ] - if "BUILD_URL" in os.environ: - body += [ "" ] - body += [ "Console output is available %s." % (jenkins_link_for_jira("here", "console")) ] - body += [ "" ] - body += [ "This message is automatically generated." ] - return "\\n".join(body) - -def jira_post_comment(result, defect, branch, username, password): - url = "%s/rest/api/2/issue/%s/comment" % (BASE_JIRA_URL, defect) - - # Generate body for the comment and save it to a file - body = jira_generate_comment(result, branch) - write_file("%s/jira-comment.txt" % output_dir, body.replace("\\n", "\n")) - - # Send the comment to the JIRA - body = "{\"body\": \"%s\"}" % body - headers = {'Content-Type' : 'application/json'} - response = jira_request(result, url, username, password, body, headers) - body = response.read() - if response.code != 201: - msg = """Request for %s failed: - URL = '%s' - Code = '%d' - Comment = '%s' - Response = '%s' - """ % (defect, url, response.code, comment, body) - print "FATAL: %s" % (msg) - sys.exit(1) - -# hack (from hadoop) but REST api doesn't list attachments? -def jira_get_attachment(result, defect, username, password): - html = jira_get_defect_html(result, defect, username, password) - escaped_colon = re.escape("%3A") - pattern = "(/secure/attachment/[0-9]+/(bug)?%s[0-9\-]*((\.|-)v?[0-9]+)?\.(patch|txt|patch\.txt))" % (re.escape(defect)) - kafka_pattern = "(/secure/attachment/[0-9]+/(bug)?%s_[0-9]+-[0-9]+-[0-9]+_[0-9]+%s[0-9]+%s[0-9]+[0-9\-]*((\.|-)v?[0-9]+)?\.(patch|txt|patch\.txt))" % (re.escape(defect), escaped_colon, escaped_colon) - matches = [] - for match in re.findall(kafka_pattern, html, re.IGNORECASE) or re.findall(pattern, html, re.IGNORECASE): - matches += [ match[0] ] - if matches: - matches.sort() - return "%s%s" % (BASE_JIRA_URL, matches.pop()) - return None - -# Get versions from JIRA JSON object -def json_get_version(json): - versions = [] - - # Load affectedVersion field - for version in json.get("fields").get("versions"): - versions = versions + [version.get("name").strip()] - - # Load fixVersion field - for version in json.get("fields").get("fixVersions"): - versions = versions + [version.get("name").strip()] - - if not versions: - print "No Affected or Fixed version found in JIRA" - - return versions - -def git_cleanup(): - rc = execute("git clean -d -f", False) - if rc != 0: - print "ERROR: git clean failed" - rc = execute("git reset --hard HEAD", False) - if rc != 0: - print "ERROR: git reset failed" - -def git_checkout(result, branch): - if not branch: - result.fatal("Branch wasn't specified nor was correctly guessed") - return - - if execute("git checkout %s" % (branch)) != 0: - result.fatal("git checkout %s failed" % branch) - if execute("git clean -d -f") != 0: - result.fatal("git clean failed") - if execute("git reset --hard HEAD") != 0: - result.fatal("git reset failed") - if execute("git fetch origin") != 0: - result.fatal("git fetch failed") - if execute("git merge --ff-only origin/%s" % (branch)): - result.fatal("git merge failed") - -def git_apply(result, cmd, patch_file, strip, output_dir): - output_file = "%s/apply.txt" % (output_dir) - rc = execute("%s -p%s < %s 1>%s 2>&1" % (cmd, strip, patch_file, output_file)) - output = "" - if os.path.exists(output_file): - with open(output_file) as fh: - output = fh.read() - if rc == 0: - if output: - result.success("Patch applied, but there has been warnings:\n{code}%s{code}\n" % (output)) - else: - result.success("Patch applied correctly") - else: - result.fatal("failed to apply patch (exit code %d):\n{code}%s{code}\n" % (rc, output)) - -def static_test(result, patch_file, output_dir): - output_file = "%s/static-test.txt" % (output_dir) - rc = execute("grep '^+++.*/test' %s 1>%s 2>&1" % (patch_file, output_file)) - if rc == 0: - result.success("Patch add/modify test case") - else: - result.error("Patch does not add/modify any test case") - -def gradle_bootstrap(result, output_dir): - rc = execute("gradle 1>%s/bootstrap.txt 2>&1" % output_dir) - if rc == 0: - result.success("Gradle bootstrap was successful") - else: - result.fatal("failed to bootstrap project (exit code %d, %s)" % (rc, jenkins_file_link_for_jira("report", "bootstrap.txt"))) - -def gradle_clean(result, output_dir): - rc = execute("./gradlew clean 1>%s/clean.txt 2>&1" % output_dir) - if rc == 0: - result.success("Clean was successful") - else: - result.fatal("failed to clean project (exit code %d, %s)" % (rc, jenkins_file_link_for_jira("report", "clean.txt"))) - -def gradle_install(result, output_dir): - rc = execute("./gradlew jarAll 1>%s/install.txt 2>&1" % output_dir) - if rc == 0: - result.success("Patch compiled") - else: - result.fatal("failed to build with patch (exit code %d, %s)" % (rc, jenkins_file_link_for_jira("report", "install.txt"))) - -def checkstyleMain(result, output_dir): - rc = execute("./gradlew checkstyleMain 1>%s/checkstyleMain.txt 2>&1" % output_dir) - if rc == 0: - result.success("Checked style for Main") - else: - result.fatal("checkstyleMain failed with patch (exit code %d, %s)" % (rc, jenkins_file_link_for_jira("report", "checkstyleMain.txt"))) - -def checkstyleTest(result, output_dir): - rc = execute("./gradlew checkstyleTest 1>%s/checkstyleTest.txt 2>&1" % output_dir) - if rc == 0: - result.success("Checked style for Test") - else: - result.fatal("checkstyleTest failed with patch (exit code %d, %s)" % (rc, jenkins_file_link_for_jira("report", "checkstyleTest.txt"))) - -def gradle_test(result, output_dir): - run_gradle_test("testAll", "unit", result, output_dir) - -def run_gradle_test(command, test_type, result, output_dir): - rc = execute("./gradlew %s 1>%s/test_%s.txt 2>&1" % (command, output_dir, test_type)) - if rc == 0: - result.success("All %s tests passed" % test_type) - else: - result.error("Some %s tests failed (%s)" % (test_type, jenkins_file_link_for_jira("report", "test_%s.txt" % test_type))) - failed_tests = [] - fd = open("%s/test_%s.txt" % (output_dir, test_type), "r") - for line in fd: - if "FAILED" in line and " > " in line: - failed_tests += [line] - fd.close() - for failed_test in set(failed_tests): - result.error("Failed %s test: {{%s}}" % (test_type, failed_test)) - -def clean_folder(folder): - for the_file in os.listdir(folder): - file_path = os.path.join(folder, the_file) - try: - if os.path.isfile(file_path): - os.unlink(file_path) - except Exception, e: - print e - -class Result(object): - def __init__(self): - self._error = [] - self._info = [] - self._success = [] - self._fatal = None - self.exit_handler = None - self.attachment = "Not Found" - self.start_time = datetime.datetime.now() - def error(self, msg): - self._error.append(msg) - def info(self, msg): - self._info.append(msg) - def success(self, msg): - self._success.append(msg) - def fatal(self, msg): - self._fatal = msg - self.exit_handler() - self.exit() - def exit(self): - git_cleanup() - global tmp_dir - global copy_output_dir - global output_dir - if copy_output_dir: - print "INFO: Moving output to %s" % (copy_output_dir) - os.renames(output_dir, copy_output_dir) - tmp_dir = None - if tmp_dir: - print "INFO: output is located %s" % (tmp_dir) - sys.exit(0) - -usage = "usage: %prog [options]" -parser = OptionParser(usage) -parser.add_option("--branch", dest="branch", - help="Local git branch to test against", metavar="trunk") -parser.add_option("--defect", dest="defect", - help="Defect name", metavar="KAFKA-1856") -parser.add_option("--file", dest="filename", - help="Test patch file", metavar="FILE") -parser.add_option("--run-tests", dest="run_tests", - help="Run Tests", action="store_true") -parser.add_option("--username", dest="username", - help="JIRA Username", metavar="USERNAME", default="kafkaqa") -parser.add_option("--output", dest="output_dir", - help="Directory to write output", metavar="DIRECTORY") -parser.add_option("--post-results", dest="post_results", - help="Post results to JIRA (only works in defect mode)", action="store_true") -parser.add_option("--password", dest="password", - help="JIRA Password", metavar="PASSWORD") -parser.add_option("--patch-command", dest="patch_cmd", default="git apply", - help="Patch command such as `git apply' or `patch'", metavar="COMMAND") -parser.add_option("-p", "--strip", dest="strip", default="1", - help="Remove leading slashes from diff paths", metavar="N") -parser.add_option("--get-latest-patch", dest="get_latest_patch", - help="Get the latest patch attached to JIRA", action="store_true") - -(options, args) = parser.parse_args() -if not (options.defect or options.filename): - print "FATAL: Either --defect or --file is required." - sys.exit(1) - -if options.defect and options.filename: - print "FATAL: Both --defect and --file cannot be specified." - sys.exit(1) - -if options.post_results and not options.password: - print "FATAL: --post-results requires --password" - sys.exit(1) - -if options.get_latest_patch and not options.defect: - print "FATAL: --get-latest-patch requires --defect" - sys.exit(1) - -branch = options.branch -if options.output_dir and not options.output_dir.startswith('/'): - print "INFO: A temporary staging dir for output will be used to avoid deletion of output files during 'git reset'" - copy_output_dir = options.output_dir - output_dir = None -else: - output_dir = options.output_dir - copy_output_dir = None -defect = options.defect -username = options.username -password = options.password -run_tests = options.run_tests -post_results = options.post_results -strip = options.strip -get_latest_patch = options.get_latest_patch -patch_cmd = options.patch_cmd -result = Result() - -if output_dir and os.path.isdir(output_dir): - clean_folder(output_dir) -if copy_output_dir and os.path.isdir(copy_output_dir): - clean_folder(copy_output_dir) - -# Default exit handler in case that we do not want to submit results to JIRA -def log_and_exit(): - # Write down comment generated for jira (won't be posted) - write_file("%s/jira-comment.txt" % output_dir, jira_generate_comment(result, branch).replace("\\n", "\n")) - - if result._fatal: - print "FATAL: %s" % (result._fatal) - for error in result._error: - print "ERROR: %s" % (error) - for info in result._info: - print "INFO: %s" % (info) - for success in result._success: - print "SUCCESS: %s" % (success) - result.exit() - -result.exit_handler = log_and_exit - -if post_results: - def post_jira_comment_and_exit(): - jira_post_comment(result, defect, branch, username, password) - result.exit() - result.exit_handler = post_jira_comment_and_exit - -if not output_dir: - tmp_dir = tempfile.mkdtemp() - output_dir = tmp_dir - -if output_dir.endswith("/"): - output_dir = output_dir[:-1] - -if output_dir and not os.path.isdir(output_dir): - os.makedirs(output_dir) - -def get_latest_patch(): - global jira_json, json, versions, branch, attachment, patch_contents, patch_file, fh - print "Defect: %s" % defect - jira_json = jira_get_defect(result, defect, username, password) - json = json.loads(jira_json) - # JIRA must be in Patch Available state - if '"Patch Available"' not in jira_json: - print "ERROR: Defect %s not in patch available state" % (defect) - sys.exit(1) - - # If branch is not specified, let's try to guess it from JIRA details - if not branch: - versions = json_get_version(json) - branch = kafka_guess_branch(versions) - if not branch: - print "ERROR: Can't guess branch name from %s" % (versions) - sys.exit(1) - else: - print "INFO: Guessed branch as %s" % (branch) - attachment = jira_get_attachment(result, defect, username, password) - if not attachment: - print "ERROR: No attachments found for %s" % (defect) - sys.exit(1) - result.attachment = attachment - patch_contents = jira_request(result, result.attachment, username, password, None, {}).read() - patch_file = "%s/%s.patch" % (output_dir, defect) - with open(patch_file, 'a') as fh: - fh.write(patch_contents) - -if defect: - # If defect parameter is specified let's download the latest attachment - get_latest_patch() - if options.get_latest_patch: - print "Saving latest attachment of %s as %s/%s.patch" % (defect, output_dir, defect) - sys.exit(0) -elif options.filename: - patch_file = options.filename -else: - raise Exception("Not reachable") - -# Verify that we are on supported branch -if not kafka_verify_branch(branch): - print "ERROR: Unsupported branch %s" % (branch) - sys.exit(1) - -gradle_bootstrap(result, output_dir) -gradle_clean(result, output_dir) -git_checkout(result, branch) -git_apply(result, patch_cmd, patch_file, strip, output_dir) -static_test(result, patch_file, output_dir) -gradle_bootstrap(result, output_dir) -gradle_install(result, output_dir) -checkstyleMain(result, output_dir) -checkstyleTest(result, output_dir) -if run_tests: - gradle_test(result, output_dir) -else: - result.info("patch applied and built but tests did not execute") - -result.exit_handler() diff --git a/kafka-patch-review.py b/kafka-patch-review.py deleted file mode 100644 index 94873c3c29cf2..0000000000000 --- a/kafka-patch-review.py +++ /dev/null @@ -1,213 +0,0 @@ -#!/usr/bin/env python -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -import argparse -import sys -import os -import time -import datetime -import tempfile -import commands -import getpass -from jira.client import JIRA - -def get_jira_config(): - # read the config file - home=jira_home=os.getenv('HOME') - home=home.rstrip('/') - if not (os.path.isfile(home + '/jira.ini')): - jira_user=raw_input('JIRA user :') - jira_pass=getpass.getpass('JIRA password :') - jira_config = {'user':jira_user, 'password':jira_pass} - return jira_config - else: - jira_config = dict(line.strip().split('=') for line in open(home + '/jira.ini')) - return jira_config - -def get_jira(jira_config): - options = { - 'server': 'https://issues.apache.org/jira' - } - jira = JIRA(options=options,basic_auth=(jira_config['user'], jira_config['password'])) - # (Force) verify the auth was really done - jira_session=jira.session() - if (jira_session is None): - raise Exception("Failed to login to the JIRA instance") - return jira - -def cmd_exists(cmd): - status, result = commands.getstatusoutput(cmd) - return status - -def main(): - ''' main(), shut up, pylint ''' - popt = argparse.ArgumentParser(description='Kafka patch review tool') - popt.add_argument('-b', '--branch', action='store', dest='branch', required=True, help='Tracking branch to create diff against') - popt.add_argument('-j', '--jira', action='store', dest='jira', required=True, help='JIRA corresponding to the reviewboard') - popt.add_argument('-s', '--summary', action='store', dest='summary', required=False, help='Summary for the reviewboard') - popt.add_argument('-d', '--description', action='store', dest='description', required=False, help='Description for reviewboard') - popt.add_argument('-r', '--rb', action='store', dest='reviewboard', required=False, help='Review board that needs to be updated') - popt.add_argument('-t', '--testing-done', action='store', dest='testing', required=False, help='Text for the Testing Done section of the reviewboard') - popt.add_argument('-db', '--debug', action='store_true', required=False, help='Enable debug mode') - opt = popt.parse_args() - - post_review_tool = None - if (cmd_exists("post-review") == 0): - post_review_tool = "post-review" - elif (cmd_exists("rbt") == 0): - post_review_tool = "rbt post" - else: - print "please install RBTools" - sys.exit(1) - - patch_file=tempfile.gettempdir() + "/" + opt.jira + ".patch" - if opt.reviewboard: - ts = time.time() - st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d_%H:%M:%S') - patch_file=tempfile.gettempdir() + "/" + opt.jira + '_' + st + '.patch' - - # first check if rebase is needed - git_branch_hash="git rev-parse " + opt.branch - p_now=os.popen(git_branch_hash) - branch_now=p_now.read() - p_now.close() - - git_common_ancestor="git merge-base " + opt.branch + " HEAD" - p_then=os.popen(git_common_ancestor) - branch_then=p_then.read() - p_then.close() - - if branch_now != branch_then: - print 'ERROR: Your current working branch is from an older version of ' + opt.branch + '. Please rebase first by using git pull --rebase' - sys.exit(1) - - git_configure_reviewboard="git config reviewboard.url https://reviews.apache.org" - print "Configuring reviewboard url to https://reviews.apache.org" - p=os.popen(git_configure_reviewboard) - p.close() - - git_remote_update="git remote update" - print "Updating your remote branches to pull the latest changes" - p=os.popen(git_remote_update) - p.close() - - # Get JIRA configuration and login to JIRA to ensure the credentials work, before publishing the patch to the review board - print "Verifying JIRA connection configurations" - try: - jira_config=get_jira_config() - jira=get_jira(jira_config) - except: - print "Failed to login to the JIRA instance", sys.exc_info()[0], sys.exc_info()[1] - sys.exit(1) - - git_command="git format-patch " + opt.branch + " --stdout > " + patch_file - if opt.debug: - print git_command - p=os.popen(git_command) - p.close() - - print 'Getting latest patch attached to the JIRA' - tmp_dir = tempfile.mkdtemp() - get_latest_patch_command="python ./dev-utils/test-patch.py --get-latest-patch --defect " + opt.jira + " --output " + tmp_dir + " > /dev/null 2>&1" - p=os.popen(get_latest_patch_command) - p.close() - - previous_patch=tmp_dir + "/" + opt.jira + ".patch" - diff_file=tmp_dir + "/" + opt.jira + ".diff" - if os.path.isfile(previous_patch) and os.stat(previous_patch).st_size > 0: - print 'Creating diff with previous version of patch uploaded to JIRA' - diff_command = "diff " + previous_patch+ " " + patch_file + " > " + diff_file - try: - p=os.popen(diff_command) - sys.stdout.flush() - p.close() - except: - pass - print 'Diff with previous version of patch uploaded to JIRA is saved to ' + diff_file - - print 'Checking if the there are changes that need to be pushed' - if os.stat(diff_file).st_size == 0: - print 'No changes found on top of changes uploaded to JIRA' - print 'Aborting' - sys.exit(1) - - rb_command= post_review_tool + " --publish --tracking-branch " + opt.branch + " --target-groups=kafka --bugs-closed=" + opt.jira - if opt.debug: - rb_command=rb_command + " --debug" - summary="Patch for " + opt.jira - if opt.summary: - summary=opt.summary - rb_command=rb_command + " --summary \"" + summary + "\"" - if opt.description: - rb_command=rb_command + " --description \"" + opt.description + "\"" - if opt.reviewboard: - rb_command=rb_command + " -r " + opt.reviewboard - if opt.testing: - rb_command=rb_command + " --testing-done=" + opt.testing - if opt.debug: - print rb_command - p=os.popen(rb_command) - rb_url="" - for line in p: - print line - if line.startswith('http'): - rb_url = line - elif line.startswith("There don't seem to be any diffs"): - print 'ERROR: Your reviewboard was not created/updated since there was no diff to upload. The reasons that can cause this issue are 1) Your diff is not checked into your local branch. Please check in the diff to the local branch and retry 2) You are not specifying the local branch name as part of the --branch option. Please specify the remote branch name obtained from git branch -r' - p.close() - sys.exit(1) - elif line.startswith("Your review request still exists, but the diff is not attached") and not opt.debug: - print 'ERROR: Your reviewboard was not created/updated. Please run the script with the --debug option to troubleshoot the problem' - p.close() - sys.exit(1) - if p.close() != None: - print 'ERROR: reviewboard update failed. Exiting.' - sys.exit(1) - if opt.debug: - print 'rb url=',rb_url - - print 'Creating diff against', opt.branch, 'and uploading patch to JIRA',opt.jira - issue = jira.issue(opt.jira) - attachment=open(patch_file) - jira.add_attachment(issue,attachment) - attachment.close() - - comment="Created reviewboard " - if not opt.reviewboard: - print 'Created a new reviewboard',rb_url, - else: - print 'Updated reviewboard',rb_url - comment="Updated reviewboard " - - comment = comment + rb_url + ' against branch ' + opt.branch - jira.add_comment(opt.jira, comment) - - #update the JIRA status to PATCH AVAILABLE - transitions = jira.transitions(issue) - transitionsMap ={} - - for t in transitions: - transitionsMap[t['name']] = t['id'] - - if('Submit Patch' in transitionsMap): - jira.transition_issue(issue, transitionsMap['Submit Patch'] , assignee={'name': jira_config['user']} ) - - -if __name__ == '__main__': - sys.exit(main())