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:
Sean Dague 2014-07-22 10:05:59 -04:00
parent 874db1d079
commit ea7590acd5
3 changed files with 26 additions and 22 deletions

View File

@ -103,11 +103,12 @@ class RecheckWatchBot(irc.bot.SingleServerIRCBot):
class RecheckWatch(threading.Thread):
def __init__(self, ircbot, channel_config, username,
def __init__(self, ircbot, channel_config, msgs, username,
queries, host, key, commenting=True):
super(RecheckWatch, self).__init__()
self.ircbot = ircbot
self.channel_config = channel_config
self.msgs = msgs
self.log = logging.getLogger('recheckwatchbot')
self.username = username
self.queries = queries
@ -206,6 +207,7 @@ class RecheckWatch(threading.Thread):
self._read(event)
stream.leave_comment(
event,
self.msgs,
debug=not self.commenting)
except er.ResultTimedOut as e:
self.log.warning(e.message)
@ -214,6 +216,11 @@ class RecheckWatch(threading.Thread):
self.log.exception("Uncaught exception processing event.")
class MessageConfig(dict):
def __init__(self, data):
self.__dict__.update(data['messages'])
class ChannelConfig(object):
def __init__(self, data):
self.data = data
@ -272,6 +279,7 @@ def _main(args, config):
raise Exception("Channel Config must be specified in config file.")
channel_config = ChannelConfig(yaml.load(open(fp)))
msgs = MessageConfig(yaml.load(open(fp)))
if not args.noirc:
bot = RecheckWatchBot(
@ -287,6 +295,7 @@ def _main(args, config):
recheck = RecheckWatch(
bot,
channel_config,
msgs,
config.get('gerrit', 'user'),
config.get('gerrit', 'query_file'),
config.get('gerrit', 'host', 'review.openstack.org'),

View File

@ -132,6 +132,10 @@ class FailEvent(object):
x in bugs]
return urls
def bug_list(self):
"""A pretty printed bug list."""
return "- " + "\n- ".join(self.bug_urls_map())
def bug_urls_map(self):
"""Produce map of which jobs failed due to which bugs."""
if not self.get_all_bugs():
@ -324,33 +328,20 @@ class Stream(object):
if self._does_es_have_data(fevent):
return fevent
def leave_comment(self, event, debug=False):
def leave_comment(self, event, msgs, debug=False):
if event.get_all_bugs():
message = """I noticed jenkins failed, I think you hit bug(s):
- %(bugs)s
""" % {'bugs': "\n- ".join(event.bug_urls_map())}
msg = msgs['found_bug'] % {'bugs': event.bug_list()}
if event.is_fully_classified():
message += """
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]}
msg += msgs['recheck_instructions']
else:
message += """
You have some unrecognized errors."""
message += """
For bug details see: http://status.openstack.org/elastic-recheck/"""
msg += msgs['unrecognized']
msg += msgs['footer']
else:
message = ("I noticed jenkins failed, refer to: "
"https://wiki.openstack.org/wiki/"
"GerritJenkinsGithub#Test_Failures")
msg += msgs['no_bugs_found']
self.log.debug("Compiled comment for commit %s:\n%s" %
(event.name(), message))
(event.name(), msg))
if not debug:
self.gerrit.review(event.project, event.name(), message)
self.gerrit.review(event.project, event.name(), msg)
class Classifier():

View File

@ -20,6 +20,7 @@ class GerritDone(Exception):
class Gerrit(object):
reviews = []
"""A fake gerrit libobject that emits a bunch of events."""
def __init__(self, *args):
with open("elastic_recheck/tests/unit/gerrit/events.json") as f:
@ -33,3 +34,6 @@ class Gerrit(object):
return self.events.pop()
else:
raise GerritDone()
def review(self, project, name, msg):
self.reviews.append({'project': project, 'name': name, 'msg': msg})