David Caro has uploaded a new change for review. Change subject: New way of running ......................................................................
New way of running * Only one review per commit, done by the dispatcher * Hooks must output the result on stdout and the results will be aggregated * Added more python libraries * New hook that updates the external tracker metadata Change-Id: Icd602596a78f7353f70eb27a18d0cafa75869cfc Signed-off-by: David Caro <dcaro...@redhat.com> --- A .gitignore A hooks/bz/change-abandoned.update_tracker M hooks/bz/change-merged.bz.set_MODIFIED A hooks/bz/change-merged.update_tracker M hooks/bz/patchset-created.bz.1.bug_url M hooks/bz/patchset-created.bz.2.add_tracker M hooks/bz/patchset-created.bz.2.set_POST M hooks/bz/patchset-created.bz.99.review_ok A hooks/bz/patchset-created.update_tracker M hooks/bz/patchset-created.warn_if_not_merged_to_previous_branch A hooks/bz/update_tracker M hooks/hook-dispatcher A hooks/lib/__init__.py A hooks/lib/bz.py M hooks/lib/bz.sh M hooks/lib/config.py M hooks/lib/gerrit.py A hooks/lib/tools.py M hooks/lib/tools.sh 19 files changed, 408 insertions(+), 93 deletions(-) git pull ssh://gerrit.ovirt.org:29418/gerrit-admin refs/changes/96/24496/1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..feceb11 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pyc +*.sw? diff --git a/hooks/bz/change-abandoned.update_tracker b/hooks/bz/change-abandoned.update_tracker new file mode 120000 index 0000000..7a06791 --- /dev/null +++ b/hooks/bz/change-abandoned.update_tracker @@ -0,0 +1 @@ +update_tracker \ No newline at end of file diff --git a/hooks/bz/change-merged.bz.set_MODIFIED b/hooks/bz/change-merged.bz.set_MODIFIED index 731d8c7..ff9cabe 100755 --- a/hooks/bz/change-merged.bz.set_MODIFIED +++ b/hooks/bz/change-merged.bz.set_MODIFIED @@ -27,13 +27,13 @@ message='' current_patch_id="${change_url//*\/}" bug_ids=($(bz.get_bug_id "$commit")) -echo "Processing bugs ${bug_ids[@]}" +tools.log "Processing bugs ${bug_ids[@]}" for bug_id in "${bug_ids[@]}"; do bz.login -b "$bug_id" "$bz_user" "$bz_password" ### Skip downstream bugs product="$(bz.get_product "$bug_id")" if ! [[ "$product" =~ ^oVirt$ ]]; then - echo "::bug $bug_id::Not an oVirt bug, belongs to $product" + tools.log "::bug $bug_id::Not an oVirt bug, belongs to $product" continue fi ## Check if all the external bugs are closed @@ -41,21 +41,24 @@ for patch_id in $(bz.get_external_bugs "$bug_id" "$TRACKER_NAME"); do [[ "$current_patch_id" == "$patch_id" ]] && continue if $(gerrit.is_open "$patch_id"); then - echo "::bug $bug_id::Related patch $patch_id is still open" + tools.log "::bug $bug_id::Related patch $patch_id is still open" all_merged="false" fi done if [[ "$all_merged" != "true" ]]; then - echo "::bug $bug_id::Skipping because not all related patches are closed." + tools.log "::bug $bug_id::Skipping because not all related patches " \ + "are closed." continue fi ## Modify the bug status if res=$(bz.update_status "$bug_id" "MODIFIED" "$commit"); then - echo "::bug $bug_id::Status updated on bug #$bug_id for gerrit id" \ - "#${change_url//*\/} to MODIFIED${res:+\n $res}" + tools.log "::bug $bug_id::Status updated on bug #$bug_id for gerrit " \ + "id #${change_url//*\/} to MODIFIED${res:+\n $res}" + tools.review "" "" "* #$bug_id::Set MODIFIED: OK" else - echo "::bug $bug_id::Failed to update the status of bug #$bug_id for"\ - "gerrit id #${current_patch_id} to MODIFIED\n $res" + tools.log "::bug $bug_id::Failed to update the status of bug " \ + "#$bug_id for gerrit id #${current_patch_id} to MODIFIED\n $res" + tools.review "" "" "* #$bug_id::Set MODIFIED: FAILED, $res" fi done bz.clean diff --git a/hooks/bz/change-merged.update_tracker b/hooks/bz/change-merged.update_tracker new file mode 120000 index 0000000..7a06791 --- /dev/null +++ b/hooks/bz/change-merged.update_tracker @@ -0,0 +1 @@ +update_tracker \ No newline at end of file diff --git a/hooks/bz/patchset-created.bz.1.bug_url b/hooks/bz/patchset-created.bz.1.bug_url index 708a319..ff1e0b0 100755 --- a/hooks/bz/patchset-created.bz.1.bug_url +++ b/hooks/bz/patchset-created.bz.1.bug_url @@ -26,32 +26,34 @@ message="" ## Check if we have to manage that branch if ! vindex=$(tools.is_in "$branch" "${BRANCHES[@]}"); then - echo "Ignoring branch $branch" + tools.review "" "" "* Bug-Url: IGNORE, not in monitored branch (${BRANCHES[@]})" exit 2 fi bug_ids=($(bz.get_bug_id $commit)) ## break the chain if no bug-url found if [[ -z "$bug_ids" ]]; then + tools.review "" ""\ + "* Bug-Url: WARN, no bug url found, make sure header matches 'Bug-Url: ' and is a valid url." exit 2 fi bz_password="${BZ_PASS?No BZ_PASS in the config}" bz_user="${BZ_USER?No BZ_USER in the config}" bz.login "$bz_user" "$bz_password" failed="false" -echo "Got bug ids ${bug_ids[@]}" +tools.log "Got bug ids ${bug_ids[@]}" +msg="* Bug-Url: INFO, got bugs ${bug_ids[@]}" for bug_id in ${bug_ids[@]}; do if bz.is_private "$bug_id"; then - echo "$bug_id::ERROR bug is private." - message+="* Bug-Url::$bug_id::ERROR, private bug" + tools.log "$bug_id::ERROR bug is private." + msg+="\n* #$bug_id::Bug-Url: ERROR, private bug" failed="true" continue fi done if [[ "$failed" == "true" ]]; then bz.clean - gerrit.review "-1" "$message" - echo "$message" + tools.log "$message" + tools.review "-1" "" "$msg" exit 2 -else - conf.t_put message "$message" fi +tools.review "" "" "$msg" diff --git a/hooks/bz/patchset-created.bz.2.add_tracker b/hooks/bz/patchset-created.bz.2.add_tracker index a8dd679..a405ac9 100755 --- a/hooks/bz/patchset-created.bz.2.add_tracker +++ b/hooks/bz/patchset-created.bz.2.add_tracker @@ -8,10 +8,13 @@ # bugzilla submit form. # 81 -> oVirt gerrit # 82 -> RHEV gerrit +# +# This hook never fails ############################################################################### source bz.sh source gerrit.sh source conf.sh +source tools.sh add_tracker() { @@ -19,16 +22,14 @@ # Get the bug url and it's flags bz.login -b "$bug_id" "$bz_user" "$bz_password" ## Update the tracker on the bz bug - local message="$(conf.t_get message)" if ! bz.add_tracker "$bug_id" "${TRACKER_ID?}" "${change_url//*\/}"; then ## raise a warning error - message+="\n* Tracker #$bug_id: FAILED" - echo "WARNING: Failed to update tracker on bug #$bug_id for gerrit id #${change_url//*\/}" + echo "* Tracker #$bug_id: FAILED" + tools.log "WARNING: Failed to update tracker on bug #$bug_id for gerrit id #${change_url//*\/}" else - message+="\n* Tracker #$bug_id: OK" - echo "Tracker updated on bug #$bug_id for gerrit id #${change_url//*\/}" + echo "* Tracker #$bug_id: OK" + tools.log "Tracker updated on bug #$bug_id for gerrit id #${change_url//*\/}" fi - conf.t_put message "$message" return 0 } diff --git a/hooks/bz/patchset-created.bz.2.set_POST b/hooks/bz/patchset-created.bz.2.set_POST index 8815d93..08f5ea0 100755 --- a/hooks/bz/patchset-created.bz.2.set_POST +++ b/hooks/bz/patchset-created.bz.2.set_POST @@ -5,6 +5,7 @@ source bz.sh source gerrit.sh source conf.sh +source tools.sh set_POST() { @@ -15,14 +16,13 @@ ## Update the tracker on the bz bug local message="$(conf.t_get message)" if ! res=$(bz.update_status "$bug_id" "POST" "$commit"); then - message+="\n* Set POST #$bug_id: FAILED, $res" - echo "Failed to update the status of bug #$bug_id for gerrit id #${change_url//*\/} to POST" - echo " $res" + echo "* #$bug_id::Set POST: FAILED, $res" + tools.log "Failed to update the status of bug #$bug_id for gerrit id #${change_url//*\/} to POST" + tools.log " $res" else - message+="\n* Set POST #$bug_id: OK${res:+, $res}" - echo "Status updated on bug #$bug_id for gerrit id #${change_url//*\/} to POST" + echo "* #$bug_id::Set POST: OK${res:+, $res}" + tools.log "Status updated on bug #$bug_id for gerrit id #${change_url//*\/} to POST" fi - conf.t_put message "$message" return 0 } diff --git a/hooks/bz/patchset-created.bz.99.review_ok b/hooks/bz/patchset-created.bz.99.review_ok index ba17d45..f5eac6a 100755 --- a/hooks/bz/patchset-created.bz.99.review_ok +++ b/hooks/bz/patchset-created.bz.99.review_ok @@ -2,13 +2,10 @@ source gerrit.sh source conf.sh source bz.sh +source tools.sh ############################################################################### ## MAIN -## get the config -conf.load -gerrit.parse_params "$@" -message="$(conf.t_get message)" -gerrit.review "0" "$message" -echo "Got good review" +tools.review "0" "0" +tools.log "Got good review" bz.clean diff --git a/hooks/bz/patchset-created.update_tracker b/hooks/bz/patchset-created.update_tracker new file mode 120000 index 0000000..7a06791 --- /dev/null +++ b/hooks/bz/patchset-created.update_tracker @@ -0,0 +1 @@ +update_tracker \ No newline at end of file diff --git a/hooks/bz/patchset-created.warn_if_not_merged_to_previous_branch b/hooks/bz/patchset-created.warn_if_not_merged_to_previous_branch index ab1d892..ae4156d 100755 --- a/hooks/bz/patchset-created.warn_if_not_merged_to_previous_branch +++ b/hooks/bz/patchset-created.warn_if_not_merged_to_previous_branch @@ -6,9 +6,12 @@ import os from config import load_config from gerrit import Gerrit +from tools import get_parser_pc -class NonComparableVersions(Exception): pass +class NonComparableVersions(Exception): + pass + def is_newer(branch1, branch2): try: @@ -41,44 +44,23 @@ return branches -def get_parser(): - """ - Build the parser for patchset-created hook type - """ - parser = argparse.ArgumentParser( - description=('This dispatcher handles the' - ' special tags and hook' - ' execution'), - ) - for arg in ('change', 'project', 'branch', 'commit'): - parser.add_argument('--' + arg, - action='store', - required=True) - for arg in ('author', 'is-draft', 'change-url', 'comment', 'uploader', - 'patchset', 'topic'): - parser.add_argument('--' + arg, - action='store', - required=False) - parser.add_argument('-v', '--verbose', action='store_true', default=False) - return parser - - def give_warning(gerrit, commit, project, branches): - msg = ("WARNING: This patch was not merged yet on all the newer " - "branches\n Missing on: %s" % ', '.join(branches)) - gerrit.review(commit=commit, project=project, message=msg) - logging.error(msg) + long_msg = ("WARNING: This patch was not merged yet on all the newer " + "branches\n Missing on: %s" % ', '.join(branches)) + msg = ("* Merged to previous: WARN, Missing on branches %s" + % ', '.join(branches)) + print msg + logging.error(long_msg) def main(): - parser = get_parser() + parser = get_parser_pc() args, unknown = parser.parse_known_args() if args.verbose: loglevel = logging.DEBUG else: loglevel = logging.INFO - logging.basicConfig(stream=sys.stdout, - level=loglevel, + logging.basicConfig(level=loglevel, format='%(asctime)s::' + str(os.getpid()) + '::%(levelname)s::%(message)s') @@ -87,12 +69,15 @@ stable_branches = config.get('STABLE_BRANCHES', None) if stable_branches is None: logging.info('No stable branches configured, set STABLE_BRANCHES in ' - 'the config to the correct value') + 'tstream=sys.stderr,he config to the correct value') + print "* Merged to previous: IGNORE, No stable branches configured." return stable_branches = stable_branches.split(' ') if args.branch not in stable_branches: logging.info('Not in one of the stable branches %s, but in %s' % (stable_branches, args.branch)) + print "* Merged to previous: IGNORE, Not in stable branch (%s)" \ + % stable_branches return gerrit = Gerrit(config['GERRIT_SRV']) unmerged_branches = get_unmerged_newer_branches( diff --git a/hooks/bz/update_tracker b/hooks/bz/update_tracker new file mode 100755 index 0000000..d9e6a5a --- /dev/null +++ b/hooks/bz/update_tracker @@ -0,0 +1,46 @@ +#!/usr/bin/env python +import os +import logging +import sys +from config import load_config +from gerrit import Gerrit +from bz import ( + get_bug_ids, + Bugzilla, +) +from tools import get_parser_pc + + +if __name__ == '__main__': + parser = get_parser_pc() + args, unknown = parser.parse_known_args() + if args.verbose: + loglevel = logging.DEBUG + else: + loglevel = logging.INFO + logging.basicConfig(level=loglevel, + format='%(asctime)s::' + + str(os.getpid()) + + '::%(levelname)s::%(message)s') + config = load_config() + logging.debug("STARTING::PARAMS %s" % sys.argv) + bgz = Bugzilla( + user=config['BZ_USER'], + passwd=config['BZ_PASS'], + ) + gerrit = Gerrit(config['GERRIT_SRV']) + change = gerrit.query(args.commit)[0] + bugs = get_bug_ids(args.commit) + for bug_id in bugs: + logging.info("%s::Updating external" % bug_id) + bgz.update_external( + bug_id, + change['number'], + config['TRACKER_ID'], + description=change['subject'], + status=change['status'], + ) + print "* #%s::Update tracker: OK" % bug_id + if not bugs: + print "* Update tracker: IGNORE, no bug-urls found" + logging.debug("FINISHED") diff --git a/hooks/hook-dispatcher b/hooks/hook-dispatcher index 6efa97c..8ef7744 100755 --- a/hooks/hook-dispatcher +++ b/hooks/hook-dispatcher @@ -23,6 +23,15 @@ import argparse import logging from dulwich.repo import Repo +## Load also the hook libs +os.environ["PATH"] = os.environ["PATH"] + ':' \ + + os.path.dirname(os.path.realpath(__file__)) + '/lib' +os.environ["PYTHONPATH"] = os.environ.get("PYTHONPATH", "") \ + + ':' + os.path.dirname(os.path.realpath(__file__)) + '/lib' +from lib import ( + gerrit, + config, +) def csv_to_set(csv_string): @@ -225,6 +234,83 @@ return chains +def parse_stdout(stdout): + """ + The expected output format is: + + ############ + code_review_value + verified_value + multiline_msg + ############ + + Where code_review_value and verified_value can be an empty line if it's + an abstention (no modifying the value any of the previous or next hooks + in the chain set) + If any of the lines is missing then it will assumed an abstention. + + 2 lines -> No message + 1 line -> No message and no verified value + 0 lines -> Not changing anything + + And if any of the two first lines fails when converting to integer, it + will assume that's the start of the message and count the non-specified + votes as abstentions + + + Examples: + ################ + message starts here + -1 + message continues + ################ + + ^^^ this will be parsed as only message and two abstentions + + ################ + -1 + message starts here + 0 + message continues here + ################ + + ^^^ this will count as CR:-1, and the rest message + + ################ + 0 + message + ################ + + ^^^ This will count as CR:0 (will level any positive review) and the rest + message + """ + result = { + 'code_review': None, + 'verified': None, + 'msg': None, + } + stdout = stdout.splitlines() + for elem_name in ('code_review', 'verified'): + if not stdout: + return result + try: + elem = stdout.pop(0) + ## non-voting + if not elem: + elem = None + ## voting + else: + elem = int(elem) + result[elem_name] = elem + ## So we don't have a number, the message should start here + except ValueError: + ## put the line back + stdout.insert(0, elem) + break + result['msg'] = '\n'.join(stdout) or None + return result + + def run_hooks(path, hooks, chain='NONE'): """" Run the given hooks form the given path @@ -232,13 +318,9 @@ :param path: Path where the hooks are located :param hooks: hook names to run """ - ## add the hooks lib dir to the path - os.environ["PATH"] = os.environ["PATH"] + ':' \ - + os.path.dirname(os.path.realpath(__file__)) + '/lib' - os.environ["PYTHONPATH"] = os.environ.get("PYTHONPATH", "") \ - + ':' + os.path.dirname(os.path.realpath(__file__)) + '/lib' hooks.sort() params = sys.argv[1:] + global_result = None for hook in hooks: cmd = [os.path.join(path, hook)] cmd.extend(params) @@ -248,14 +330,26 @@ stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = pipe.communicate() + result = parse_stdout(output) + if global_result is None: + global_result = result + else: + for elem in ('code_review', 'verified'): + if result[elem] is not None \ + and result[elem] < global_result[elem]: + global_result[elem] = result[elem] + if result['msg']: + global_result['msg'] = str(global_result['msg']) \ + + '\n' + result['msg'] if pipe.returncode == 0: - logging.info(logstr + '\n' + output) + logging.info(logstr + '\n' + str(result)) error and logging.warn(logstr + '\n' + error) else: - logging.warn(logstr + '\n' + output) + logging.warn(logstr + '\n' + str(result)) error and logging.error(logstr + '\n' + error) logging.warn(chain + "::BROKEN WITH " + str(pipe.returncode)) - return pipe.returncode + return global_result + return global_result def run_chains(path, hooks): @@ -266,16 +360,17 @@ :param hooks: hook names to run """ ## add the hooks lib dir to the path + results = {} logging.info("::RUNNING HOOKS::%s", hooks) chains = get_chains(hooks) for c_name, c_hooks in chains.iteritems(): logging.info(c_name + "::STARTING") - ret_code = run_hooks(path, c_hooks, c_name) - if ret_code == 1: - logging.error("ABORTING::got return code 1.") - return ret_code - elif ret_code == 0: - logging.info(c_name + "::FINISHED OK") + results[c_name] = run_hooks(path, c_hooks, c_name) + if results[c_name]['msg'] is None: + results[c_name]['msg'] = '* %s: OK' % c_name + logging.info(c_name + "::FINISHED with result:\n" + + str(results[c_name])) + return results def get_hook_type(opts): @@ -294,6 +389,40 @@ return 'change-abandoned' else: return os.path.basename(__file__) + + +def send_summary(change_id, project, results): + """ + Parse all the results and generate the summary review + + :param change_id: string to identify the change with, usually the commit + hash or the change-id,patchset pair + :param results: Dictionary with the compiled results for all the chains + + It will use the lowest values for the votes, skipping the ones that are + `None`, and merge all the messages into one. + + For example, if it has two chains, one with CR:0 and one with CR:1, the + result will be CR:0. + """ + msg = [] + code_review = 0 + verified = 0 + ## Generate final review + for result in results.itervalues(): + if result['msg']: + msg.append(result['msg']) + if result['code_review'] is not None \ + and result['code_review'] < code_review: + code_review = result['code_review'] + if result['verified'] is not None \ + and result['verified'] < verified: + verified = result['verified'] + msg = '\n'.join(msg) + g_server = gerrit.Gerrit(config.load_config()['GERRIT_SRV']) + g_server.review(change_id, project, msg, code_review, verified) + logging.info(" FINAL REVIEW\nCR: %d\nV: %d\nMSG:\n%s" + % (code_review, verified, msg)) def main(): @@ -318,9 +447,13 @@ hook_type) logging.info("::AVAILABLE HOOKS::%s", hooks) tags = {} + change_ident = None if known_args.commit: ## get tags from the commit message tags.update(get_commit_tags(known_args.commit)) + change_ident = known_args.commit + elif known_args.patchset and known_args.change: + change_ident = "%s,%s" % (known_args.patchset, known_args.change) if known_args.comment: ## and from the gerrit comment tags.update(get_comment_tags(known_args.comment)) @@ -328,9 +461,14 @@ ## Execute the functions with the tag value, the current available ## hooks, and the args so they can be modified hooks = fun(tag_val, hooks, known_args) - ## keep them sorted (will be sorted again later though) - hooks.sort() - run_chains(os.path.join(os.environ['GIT_DIR'], 'hooks'), hooks) + ## if we found any hooks, run them + if hooks: + ## keep them sorted (will be sorted again later though) + hooks.sort() + results = run_chains(os.path.join(os.environ['GIT_DIR'], 'hooks'), + hooks) + if change_ident: + send_summary(change_ident, known_args.project, results) logging.info("FINISHED") diff --git a/hooks/lib/__init__.py b/hooks/lib/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/hooks/lib/__init__.py diff --git a/hooks/lib/bz.py b/hooks/lib/bz.py new file mode 100644 index 0000000..935bee5 --- /dev/null +++ b/hooks/lib/bz.py @@ -0,0 +1,95 @@ +#!/user/bin/env python +import os +import xmlrpclib +import re +from dulwich.repo import Repo +import logging + + +class Bugzilla(object): + def __init__(self, user=None, passwd=None, + url='https://bugzilla.redhat.com/xmlrpc.cgi'): + self.rpc = xmlrpclib.ServerProxy(url) + self.user = user + self.passwd = passwd + + def wrap(self, dictionary): + if self.user: + dictionary['Bugzilla_login'] = self.user + if self.passwd: + dictionary['Bugzilla_password'] = self.passwd + return dictionary + + def __getattr__(self, what): + return getattr(self.rpc, what) + + def get_external(self, bug_id, external_bug_id): + bug = self.rpc.Bug.get(self.wrap({ + 'ids': bug_id, + 'extra_fields': ['external_bugs'], + })) + if not bug['bugs']: + logging.error("Unable to get bug %s\n%s" + % (str(bug_id), bug['faults'])) + return None + ## Only one response when asking by the commit hash + bug = bug['bugs'][0] + for external in bug['external_bugs']: + if external['ext_bz_bug_id'] == external_bug_id: + return external + return None + + def update_external(self, bug_id, external_bug_id, ext_type_id, + status=None, description=None): + orig_external = self.get_external(bug_id, external_bug_id) + external = {} + external['ext_type_id'] = ext_type_id + external['ext_bz_bug_id'] = external_bug_id + if not orig_external: + if description is not None: + external['ext_description'] = description + if status is not None: + external['ext_status'] = status + self.ExternalBugs.add_external_bug(self.wrap({ + 'bug_ids': [bug_id], + 'external_bugs': [external], + })) + else: + if description is not None: + external['ext_description'] = description + else: + external['ext_description'] = orig_external['ext_description'] + if status is not None: + external['ext_status'] = status + else: + external['ext_status'] = orig_external['ext_status'] + self.ExternalBugs.update_external_bug(self.wrap(external)) + + +def get_bug_ids(commit): + """ + Get the bug ids that were specified in the commit message + + :param commit: Commit to get the message from + """ + bug_regexp = re.compile( + r''' + ^Bug-Url:\ https?://bugzilla\.redhat\.com/ ## base url + (show_bug\.cgi\?id=)? ## optional cgi + (?P<bug_id>\d+) ## bug id itself + $''', + re.VERBOSE + ) + revert_regexp = re.compile( + '^This reverts commit (?P<commit>[[:alnum:]]+)$') + repo = Repo(os.environ['GIT_DIR']) + bugs = [] + message = repo[commit].message + for line in message.splitlines(): + rev_match = revert_regexp.search(line) + if rev_match and rev_match.groupsdict()['commit'] != commit: + return get_bug_ids(rev_match.groupsdict()['commit']) + match = bug_regexp.search(line) + if match: + bugs.append(match.groupdict()['bug_id']) + return bugs diff --git a/hooks/lib/bz.sh b/hooks/lib/bz.sh index a17e235..ceb66ad 100644 --- a/hooks/lib/bz.sh +++ b/hooks/lib/bz.sh @@ -93,9 +93,9 @@ if [[ $rc -eq 0 ]]; then rm -f "/tmp/update_bug_log.${bug_id}" else - echo "Error while updating bug #${bug_id} with post_data, response data"\ - "at /tmp/update_bug_log.${bug_id}" - echo "Sent data: $post_data" + tools.log "Error while updating bug #${bug_id} with post_data, " \ + "response data at /tmp/update_bug_log.${bug_id}" + tools.log "Sent data: $post_data" fi ## clean the old bug data from all caches, if any rm -f /tmp/bz_cache.*.${bug_id}.* diff --git a/hooks/lib/config.py b/hooks/lib/config.py index 5d28a17..7853bdd 100644 --- a/hooks/lib/config.py +++ b/hooks/lib/config.py @@ -58,7 +58,7 @@ return dict.__getitem__(self, item) except KeyError: logger.error('Unable to get config value %s from any of the ' - 'config files [%s]' % (item,', '.join(self.files))) + 'config files [%s]' % (item, ', '.join(self.files))) raise diff --git a/hooks/lib/gerrit.py b/hooks/lib/gerrit.py index 3b09a42..3fb6ba9 100644 --- a/hooks/lib/gerrit.py +++ b/hooks/lib/gerrit.py @@ -20,12 +20,12 @@ ) def generate_cmd(self, action, *options): - cmd = list(self.cmd) + cmd = list(self.cmd) cmd.append(action) cmd.extend(options) return cmd - def review(self, commit, message, project, verify=None, review=None): + def review(self, commit, project, message, verify=None, review=None): gerrit_cmd = self.generate_cmd( 'review', commit, @@ -33,12 +33,12 @@ '--project=%s' % project, ) if verify is not None: - gerrit_cmd.append('--verify=%s' % str(verify)) + gerrit_cmd.append('--verified=%s' % str(verify)) if review is not None: gerrit_cmd.append('--code-review=%s' % str(review)) cmd = subprocess.Popen(gerrit_cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) out, err = cmd.communicate() if cmd.returncode: raise Exception("Execution of %s returned %d:\n%s" @@ -55,8 +55,8 @@ ) logger.debug("Executing %s" % ' '.join(gerrit_cmd)) cmd = subprocess.Popen(gerrit_cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) out, err = cmd.communicate() if cmd.returncode: raise Exception("Execution of %s returned %d:\n%s" diff --git a/hooks/lib/tools.py b/hooks/lib/tools.py new file mode 100644 index 0000000..86b1e25 --- /dev/null +++ b/hooks/lib/tools.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +import argparse + + +def get_parser_pc(): + """ + Build the parser for patchset-created hook type + """ + parser = argparse.ArgumentParser( + description=('This dispatcher handles the' + ' special tags and hook' + ' execution'), + ) + for arg in ('change', 'project', 'branch', 'commit'): + parser.add_argument('--' + arg, + action='store', + required=True) + for arg in ('author', 'is-draft', 'change-url', 'comment', 'uploader', + 'patchset', 'topic'): + parser.add_argument('--' + arg, + action='store', + required=False) + parser.add_argument('-v', '--verbose', action='store_true', default=False) + return parser diff --git a/hooks/lib/tools.sh b/hooks/lib/tools.sh index 09fbde7..3d73688 100644 --- a/hooks/lib/tools.sh +++ b/hooks/lib/tools.sh @@ -63,3 +63,22 @@ local length="${2:-10}" echo "$what" | md5sum | head -c$length } + + +## log to stderr +tools.log() +{ + echo "$@" >&2 +} + + +## print a review message with the format expeted by the hook dispatcher +tools.review() +{ + local cr="${1}" + local ver="${2}" + local msg="${3}" + echo "$cr" + echo "$ver" + echo -e "$msg" +} -- To view, visit http://gerrit.ovirt.org/24496 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Icd602596a78f7353f70eb27a18d0cafa75869cfc Gerrit-PatchSet: 1 Gerrit-Project: gerrit-admin Gerrit-Branch: master Gerrit-Owner: David Caro <dcaro...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches