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): 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'),

View File

@ -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():

View File

@ -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})