Home | History | Annotate | Download | only in bot
      1 # Copyright (c) 2010 Google Inc. All rights reserved.
      2 #
      3 # Redistribution and use in source and binary forms, with or without
      4 # modification, are permitted provided that the following conditions are
      5 # met:
      6 #
      7 #     * Redistributions of source code must retain the above copyright
      8 # notice, this list of conditions and the following disclaimer.
      9 #     * Redistributions in binary form must reproduce the above
     10 # copyright notice, this list of conditions and the following disclaimer
     11 # in the documentation and/or other materials provided with the
     12 # distribution.
     13 #     * Neither the name of Google Inc. nor the names of its
     14 # contributors may be used to endorse or promote products derived from
     15 # this software without specific prior written permission.
     16 #
     17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 
     29 import random
     30 from webkitpy.common.config import irc as config_irc
     31 
     32 from webkitpy.common.config import urls
     33 from webkitpy.common.config.committers import CommitterList
     34 from webkitpy.common.net.bugzilla import parse_bug_id
     35 from webkitpy.common.system.executive import ScriptError
     36 from webkitpy.tool.bot.queueengine import TerminateQueue
     37 from webkitpy.tool.grammar import join_with_separators
     38 
     39 # FIXME: Merge with Command?
     40 class IRCCommand(object):
     41     def execute(self, nick, args, tool, sheriff):
     42         raise NotImplementedError, "subclasses must implement"
     43 
     44 
     45 class LastGreenRevision(IRCCommand):
     46     def execute(self, nick, args, tool, sheriff):
     47         return "%s: %s" % (nick,
     48             urls.view_revision_url(tool.buildbot.last_green_revision()))
     49 
     50 
     51 class Restart(IRCCommand):
     52     def execute(self, nick, args, tool, sheriff):
     53         tool.irc().post("Restarting...")
     54         raise TerminateQueue()
     55 
     56 
     57 class Rollout(IRCCommand):
     58     def _parse_args(self, args):
     59         read_revision = True
     60         rollout_reason = []
     61         # the first argument must be a revision number
     62         svn_revision_list = [args[0].lstrip("r")]
     63         if not svn_revision_list[0].isdigit():
     64             read_revision = False
     65 
     66         for arg in args[1:]:
     67             if arg.lstrip("r").isdigit() and read_revision:
     68                 svn_revision_list.append(arg.lstrip("r"))
     69             else:
     70                 read_revision = False
     71                 rollout_reason.append(arg)
     72 
     73         return svn_revision_list, rollout_reason
     74 
     75     def execute(self, nick, args, tool, sheriff):
     76         svn_revision_list, rollout_reason = self._parse_args(args)
     77 
     78         if (len(svn_revision_list) == 0) or (len(rollout_reason) == 0):
     79             tool.irc().post("%s: Usage: SVN_REVISION [SVN_REVISIONS] REASON" % nick)
     80             return
     81 
     82         rollout_reason = " ".join(rollout_reason)
     83 
     84         tool.irc().post("Preparing rollout for %s..." %
     85                         join_with_separators(["r" + str(revision) for revision in svn_revision_list]))
     86         try:
     87             complete_reason = "%s (Requested by %s on %s)." % (
     88                 rollout_reason, nick, config_irc.channel)
     89             bug_id = sheriff.post_rollout_patch(svn_revision_list, complete_reason)
     90             bug_url = tool.bugs.bug_url_for_bug_id(bug_id)
     91             tool.irc().post("%s: Created rollout: %s" % (nick, bug_url))
     92         except ScriptError, e:
     93             tool.irc().post("%s: Failed to create rollout patch:" % nick)
     94             tool.irc().post("%s" % e)
     95             bug_id = parse_bug_id(e.output)
     96             if bug_id:
     97                 tool.irc().post("Ugg...  Might have created %s" %
     98                     tool.bugs.bug_url_for_bug_id(bug_id))
     99 
    100 
    101 class Help(IRCCommand):
    102     def execute(self, nick, args, tool, sheriff):
    103         return "%s: Available commands: %s" % (nick, ", ".join(commands.keys()))
    104 
    105 
    106 class Hi(IRCCommand):
    107     def execute(self, nick, args, tool, sheriff):
    108         quips = tool.bugs.quips()
    109         quips.append('"Only you can prevent forest fires." -- Smokey the Bear')
    110         return random.choice(quips)
    111 
    112 
    113 class Whois(IRCCommand):
    114     def execute(self, nick, args, tool, sheriff):
    115         if len(args) != 1:
    116             return "%s: Usage: BUGZILLA_EMAIL" % nick
    117         email = args[0]
    118         committer = CommitterList().committer_by_email(email)
    119         if not committer:
    120             return "%s: Sorry, I don't know %s. Maybe you could introduce me?" % (nick, email)
    121         if not committer.irc_nickname:
    122             return "%s: %s hasn't told me their nick. Boo hoo :-(" % (nick, email)
    123         return "%s: %s is %s. Why do you ask?" % (nick, email, committer.irc_nickname)
    124 
    125 
    126 class Eliza(IRCCommand):
    127     therapist = None
    128 
    129     def __init__(self):
    130         if not self.therapist:
    131             import webkitpy.thirdparty.autoinstalled.eliza as eliza
    132             Eliza.therapist = eliza.eliza()
    133 
    134     def execute(self, nick, args, tool, sheriff):
    135         return "%s: %s" % (nick, self.therapist.respond(" ".join(args)))
    136 
    137 
    138 # FIXME: Lame.  We should have an auto-registering CommandCenter.
    139 commands = {
    140     "help": Help,
    141     "hi": Hi,
    142     "last-green-revision": LastGreenRevision,
    143     "restart": Restart,
    144     "rollout": Rollout,
    145     "whois": Whois,
    146 }
    147