X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=tools%2Fdistchanges%2Fgerritquery.py;h=b6cddc5cdb22fd526cab938ec18994779f6609b8;hb=605ceec45e75d1e008131e1fec051e29ef71cc50;hp=e46756f78121f9c41826862c72808e9d13ba0370;hpb=8d9fde3e0d522eb4714fbbee642054560143b948;p=integration%2Ftest.git diff --git a/tools/distchanges/gerritquery.py b/tools/distchanges/gerritquery.py index e46756f781..b6cddc5cdb 100644 --- a/tools/distchanges/gerritquery.py +++ b/tools/distchanges/gerritquery.py @@ -3,6 +3,7 @@ This module contains functions to manipulate gerrit queries. """ import datetime import json +import logging import os import re import shlex @@ -10,11 +11,11 @@ import subprocess import traceback import sys - # TODO: Haven't tested python 3 if sys.version < '3': import urllib import urlparse + urlencode = urllib.urlencode urljoin = urlparse.urljoin urlparse = urlparse.urlparse @@ -22,12 +23,16 @@ if sys.version < '3': else: import urllib.parse import urllib.request + urlencode = urllib.parse.urlencode urljoin = urllib.parse.urljoin urlparse = urllib.parse.urlparse do_input = input +logger = logging.getLogger("changes.gerritquery") + + class GitReviewException(Exception): EXIT_CODE = 127 @@ -60,7 +65,6 @@ class GerritQuery: remote_url = REMOTE_URL branch = BRANCH query_limit = QUERY_LIMIT - verbose = 0 def __init__(self, remote_url, branch, query_limit, verbose): self.remote_url = remote_url @@ -68,21 +72,21 @@ class GerritQuery: self.query_limit = query_limit self.verbose = verbose - def set_verbose(self, verbose): - self.verbose = verbose - @staticmethod def print_safe_encoding(string): - if sys.stdout.encoding is None: - # just print(string) could still throw a UnicodeEncodeError sometimes so casting string to unicode - print(unicode(string)) - else: - print(string.encode(sys.stdout.encoding, 'replace')) + try: + if type(string) == unicode: + encoding = 'utf-8' + if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding: + encoding = sys.stdout.encoding + return string.encode(encoding or 'utf-8', 'replace') + else: + return str(string) + except: + return str(string) def run_command_status(self, *argv, **kwargs): - - if self.verbose >= 2: - print(datetime.datetime.now(), "Running:", " ".join(argv)) + logger.debug("%s Running: %s", datetime.datetime.now(), " ".join(argv)) if len(argv) == 1: # for python2 compatibility with shlex if sys.version_info < (3,) and isinstance(argv[0], unicode): @@ -179,33 +183,44 @@ class GerritQuery: else: userhost = "%s@%s" % (username, hostname) - if self.verbose >= 2: - print("gerrit request %s %s" % (self.remote_url, request)) - output = self.run_command_exc( - CommandFailed, - "ssh", "-x" + port_data, userhost, - request) - if self.verbose >= 3: - self.print_safe_encoding(output) + logger.debug("gerrit request %s %s" % (self.remote_url, request)) + output = self.run_command_exc(CommandFailed, "ssh", "-x" + port_data, userhost, request) + if logger.isEnabledFor(logging.DEBUG): + logger.debug("%s", self.print_safe_encoding(output)) return output - def make_gerrit_query(self, project, changeid=None, limit=1, msg=None): + def make_gerrit_query(self, project, changeid=None, limit=1, msg=None, status=None, comments=False, commitid=None): """ Make a gerrit query by combining the given options. :param str project: The project to search :param str changeid: A Change-Id to search :param int limit: The number of items to return - :param str msg: A commit-msg to search + :param str msg or None: A commit-msg to search + :param str status or None: The gerrit status, i.e. merged + :param bool comments: If true include comments + :param commitid: A commit hash to search :return str: A gerrit query """ - query = "gerrit query --format=json limit:%d status:merged --all-approvals " \ - "project:%s branch:%s" \ - % (limit, project, self.branch) + + if project == "odlparent" or project == "yangtools": + query = "gerrit query --format=json limit:%d " \ + "project:%s" \ + % (limit, project) + else: + query = "gerrit query --format=json limit:%d " \ + "project:%s branch:%s" \ + % (limit, project, self.branch) if changeid: query += " change:%s" % changeid if msg: - query += " message:%s" % msg + query += " message:{%s}" % msg + if commitid: + query += " commit:%s" % commitid + if status: + query += " status:%s --all-approvals" % status + if comments: + query += " --comments" return query def parse_gerrit(self, line, parse_exc=Exception): @@ -229,6 +244,7 @@ class GerritQuery: parsed['subject'] = data['subject'] parsed['url'] = data['url'] parsed['lastUpdated'] = data['lastUpdated'] + parsed['grantedOn'] = 0 if "patchSets" in data: patch_sets = data['patchSets'] for patch_set in reversed(patch_sets): @@ -238,14 +254,23 @@ class GerritQuery: if 'type' in approval and approval['type'] == 'SUBM': parsed['grantedOn'] = approval['grantedOn'] break - if parsed['grantedOn']: + if parsed['grantedOn'] != 0: + break + if "comments" in data: + comments = data['comments'] + for comment in reversed(comments): + if "message" in comment and "timestamp" in comment: + message = comment['message'] + timestamp = comment['timestamp'] + if "Build Started" in message and "patch-test" in message: + parsed['grantedOn'] = timestamp break except Exception: - if self.verbose: - print("Failed to decode JSON: %s" % traceback.format_exc()) - self.print_safe_encoding(line) + logger.warn("Failed to decode JSON: %s", traceback.format_exc()) + if logger.isEnabledFor(logging.DEBUG): + logger.warn(self.print_safe_encoding(line)) except Exception as err: - print("Exception: %s" % traceback.format_exc()) + logger.warn("Exception: %s", traceback.format_exc()) raise parse_exc(err) return parsed @@ -259,17 +284,17 @@ class GerritQuery: :return list: Lines of the JSON """ lines = [] - for line in changes.split("\n"): - if line.find('"type":"error","message"') != -1: - print("there was a query error") - continue - if line.find('stats') == -1: + skipped = 0 + for i, line in enumerate(changes.split("\n")): + if line.find('"grantedOn":') != -1: lines.append(line) - if self.verbose >= 2: - print("get_gerrit_lines: found %d lines" % len(lines)) + else: + logger.debug("skipping: {}".format(line)) + skipped += 1 + logger.debug("get_gerrit_lines: found {} lines, skipped: {}".format(len(lines), skipped)) return lines - def get_gerrits(self, project, changeid=None, limit=1, msg=None): + def get_gerrits(self, project, changeid=None, limit=1, msg=None, status=None, comments=False, commitid=None): """ Get a list of gerrits from gerrit query request. @@ -282,16 +307,29 @@ class GerritQuery: :param str project: The project to search :param str or None changeid: A Change-Id to search :param int limit: The number of items to return - :param str msg: A commit-msg to search - :return str: A gerrit query + :param str or None msg: A commit-msg to search + :param str or None status: The gerrit status, i.e. merged + :param bool comments: If true include comments + :param commitid: A commit hash to search + :return str: List of gerrits sorted by merge time """ - query = self.make_gerrit_query(project, changeid, limit, msg) + logger.debug("get_gerrits: project: %s, changeid: %s, limit: %d, msg: %s, status: %s, comments: %s, " + + "commitid: %s", + project, changeid, limit, msg, status, comments, commitid) + query = self.make_gerrit_query(project, changeid, limit, msg, status, comments, commitid) changes = self.gerrit_request(query) lines = self.extract_lines_from_json(changes) gerrits = [] + sorted_gerrits = [] for line in lines: gerrits.append(self.parse_gerrit(line)) from operator import itemgetter - sorted_gerrits = sorted(gerrits, key=itemgetter('grantedOn'), reverse=True) + if gerrits is None: + logger.warn("No gerrits were found for %s", project) + return gerrits + try: + sorted_gerrits = sorted(gerrits, key=itemgetter('grantedOn'), reverse=True) + except KeyError as e: + logger.warn("KeyError exception in %s, %s", project, str(e)) return sorted_gerrits