add support for an external message catalog
Instead of having the messages inline, we should do them in the yaml file so that changing the UX for the bot reporting isn't a code change. Depends-On: I9208123a4cb3be02c272cd8a6eba460f4130a960 Change-Id: I8fdb07f9964f616addba6e8f25e5bd9de27d077a
This commit is contained in:
parent
874db1d079
commit
ea7590acd5
@ -103,11 +103,12 @@ class RecheckWatchBot(irc.bot.SingleServerIRCBot):
|
|||||||
|
|
||||||
|
|
||||||
class RecheckWatch(threading.Thread):
|
class RecheckWatch(threading.Thread):
|
||||||
def __init__(self, ircbot, channel_config, username,
|
def __init__(self, ircbot, channel_config, msgs, username,
|
||||||
queries, host, key, commenting=True):
|
queries, host, key, commenting=True):
|
||||||
super(RecheckWatch, self).__init__()
|
super(RecheckWatch, self).__init__()
|
||||||
self.ircbot = ircbot
|
self.ircbot = ircbot
|
||||||
self.channel_config = channel_config
|
self.channel_config = channel_config
|
||||||
|
self.msgs = msgs
|
||||||
self.log = logging.getLogger('recheckwatchbot')
|
self.log = logging.getLogger('recheckwatchbot')
|
||||||
self.username = username
|
self.username = username
|
||||||
self.queries = queries
|
self.queries = queries
|
||||||
@ -206,6 +207,7 @@ class RecheckWatch(threading.Thread):
|
|||||||
self._read(event)
|
self._read(event)
|
||||||
stream.leave_comment(
|
stream.leave_comment(
|
||||||
event,
|
event,
|
||||||
|
self.msgs,
|
||||||
debug=not self.commenting)
|
debug=not self.commenting)
|
||||||
except er.ResultTimedOut as e:
|
except er.ResultTimedOut as e:
|
||||||
self.log.warning(e.message)
|
self.log.warning(e.message)
|
||||||
@ -214,6 +216,11 @@ class RecheckWatch(threading.Thread):
|
|||||||
self.log.exception("Uncaught exception processing event.")
|
self.log.exception("Uncaught exception processing event.")
|
||||||
|
|
||||||
|
|
||||||
|
class MessageConfig(dict):
|
||||||
|
def __init__(self, data):
|
||||||
|
self.__dict__.update(data['messages'])
|
||||||
|
|
||||||
|
|
||||||
class ChannelConfig(object):
|
class ChannelConfig(object):
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
self.data = data
|
self.data = data
|
||||||
@ -272,6 +279,7 @@ def _main(args, config):
|
|||||||
raise Exception("Channel Config must be specified in config file.")
|
raise Exception("Channel Config must be specified in config file.")
|
||||||
|
|
||||||
channel_config = ChannelConfig(yaml.load(open(fp)))
|
channel_config = ChannelConfig(yaml.load(open(fp)))
|
||||||
|
msgs = MessageConfig(yaml.load(open(fp)))
|
||||||
|
|
||||||
if not args.noirc:
|
if not args.noirc:
|
||||||
bot = RecheckWatchBot(
|
bot = RecheckWatchBot(
|
||||||
@ -287,6 +295,7 @@ def _main(args, config):
|
|||||||
recheck = RecheckWatch(
|
recheck = RecheckWatch(
|
||||||
bot,
|
bot,
|
||||||
channel_config,
|
channel_config,
|
||||||
|
msgs,
|
||||||
config.get('gerrit', 'user'),
|
config.get('gerrit', 'user'),
|
||||||
config.get('gerrit', 'query_file'),
|
config.get('gerrit', 'query_file'),
|
||||||
config.get('gerrit', 'host', 'review.openstack.org'),
|
config.get('gerrit', 'host', 'review.openstack.org'),
|
||||||
|
@ -132,6 +132,10 @@ class FailEvent(object):
|
|||||||
x in bugs]
|
x in bugs]
|
||||||
return urls
|
return urls
|
||||||
|
|
||||||
|
def bug_list(self):
|
||||||
|
"""A pretty printed bug list."""
|
||||||
|
return "- " + "\n- ".join(self.bug_urls_map())
|
||||||
|
|
||||||
def bug_urls_map(self):
|
def bug_urls_map(self):
|
||||||
"""Produce map of which jobs failed due to which bugs."""
|
"""Produce map of which jobs failed due to which bugs."""
|
||||||
if not self.get_all_bugs():
|
if not self.get_all_bugs():
|
||||||
@ -324,33 +328,20 @@ class Stream(object):
|
|||||||
if self._does_es_have_data(fevent):
|
if self._does_es_have_data(fevent):
|
||||||
return fevent
|
return fevent
|
||||||
|
|
||||||
def leave_comment(self, event, debug=False):
|
def leave_comment(self, event, msgs, debug=False):
|
||||||
if event.get_all_bugs():
|
if event.get_all_bugs():
|
||||||
message = """I noticed jenkins failed, I think you hit bug(s):
|
msg = msgs['found_bug'] % {'bugs': event.bug_list()}
|
||||||
|
|
||||||
- %(bugs)s
|
|
||||||
""" % {'bugs': "\n- ".join(event.bug_urls_map())}
|
|
||||||
if event.is_fully_classified():
|
if event.is_fully_classified():
|
||||||
message += """
|
msg += msgs['recheck_instructions']
|
||||||
We don't automatically recheck or reverify, so please consider
|
|
||||||
doing that manually if someone hasn't already. For a code review
|
|
||||||
which is not yet approved, you can recheck by leaving a code
|
|
||||||
review comment with just the text:
|
|
||||||
|
|
||||||
recheck bug %(bug)s""" % {'bug': list(event.get_all_bugs())[0]}
|
|
||||||
else:
|
else:
|
||||||
message += """
|
msg += msgs['unrecognized']
|
||||||
You have some unrecognized errors."""
|
msg += msgs['footer']
|
||||||
message += """
|
|
||||||
For bug details see: http://status.openstack.org/elastic-recheck/"""
|
|
||||||
else:
|
else:
|
||||||
message = ("I noticed jenkins failed, refer to: "
|
msg += msgs['no_bugs_found']
|
||||||
"https://wiki.openstack.org/wiki/"
|
|
||||||
"GerritJenkinsGithub#Test_Failures")
|
|
||||||
self.log.debug("Compiled comment for commit %s:\n%s" %
|
self.log.debug("Compiled comment for commit %s:\n%s" %
|
||||||
(event.name(), message))
|
(event.name(), msg))
|
||||||
if not debug:
|
if not debug:
|
||||||
self.gerrit.review(event.project, event.name(), message)
|
self.gerrit.review(event.project, event.name(), msg)
|
||||||
|
|
||||||
|
|
||||||
class Classifier():
|
class Classifier():
|
||||||
|
@ -20,6 +20,7 @@ class GerritDone(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class Gerrit(object):
|
class Gerrit(object):
|
||||||
|
reviews = []
|
||||||
"""A fake gerrit libobject that emits a bunch of events."""
|
"""A fake gerrit libobject that emits a bunch of events."""
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
with open("elastic_recheck/tests/unit/gerrit/events.json") as f:
|
with open("elastic_recheck/tests/unit/gerrit/events.json") as f:
|
||||||
@ -33,3 +34,6 @@ class Gerrit(object):
|
|||||||
return self.events.pop()
|
return self.events.pop()
|
||||||
else:
|
else:
|
||||||
raise GerritDone()
|
raise GerritDone()
|
||||||
|
|
||||||
|
def review(self, project, name, msg):
|
||||||
|
self.reviews.append({'project': project, 'name': name, 'msg': msg})
|
||||||
|
Loading…
Reference in New Issue
Block a user