1#!/usr/bin/env python 2# Copyright (c) 2009, Google Inc. All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are 6# met: 7# 8# * Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# * Redistributions in binary form must reproduce the above 11# copyright notice, this list of conditions and the following disclaimer 12# in the documentation and/or other materials provided with the 13# distribution. 14# * Neither the name of Google Inc. nor the names of its 15# contributors may be used to endorse or promote products derived from 16# this software without specific prior written permission. 17# 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30from StringIO import StringIO 31 32from webkitpy.commands.queues import AbstractReviewQueue 33from webkitpy.committers import CommitterList 34from webkitpy.executive import ScriptError 35from webkitpy.webkitport import WebKitPort 36from webkitpy.queueengine import QueueEngine 37 38 39class AbstractEarlyWarningSystem(AbstractReviewQueue): 40 _build_style = "release" 41 42 def __init__(self): 43 AbstractReviewQueue.__init__(self) 44 self.port = WebKitPort.port(self.port_name) 45 46 def should_proceed_with_work_item(self, patch): 47 try: 48 self.run_webkit_patch([ 49 "build", 50 self.port.flag(), 51 "--build-style=%s" % self._build_style, 52 "--force-clean", 53 "--quiet"]) 54 self._update_status("Building", patch) 55 except ScriptError, e: 56 self._update_status("Unable to perform a build") 57 return False 58 return True 59 60 def _review_patch(self, patch): 61 self.run_webkit_patch([ 62 "build-attachment", 63 self.port.flag(), 64 "--build-style=%s" % self._build_style, 65 "--force-clean", 66 "--quiet", 67 "--non-interactive", 68 "--parent-command=%s" % self.name, 69 "--no-update", 70 patch.id()]) 71 72 @classmethod 73 def handle_script_error(cls, tool, state, script_error): 74 is_svn_apply = script_error.command_name() == "svn-apply" 75 status_id = cls._update_status_for_script_error(tool, state, script_error, is_error=is_svn_apply) 76 if is_svn_apply: 77 QueueEngine.exit_after_handled_error(script_error) 78 results_link = tool.status_server.results_url_for_status(status_id) 79 message = "Attachment %s did not build on %s:\nBuild output: %s" % (state["patch"].id(), cls.port_name, results_link) 80 tool.bugs.post_comment_to_bug(state["patch"].bug_id(), message, cc=cls.watchers) 81 exit(1) 82 83 84class GtkEWS(AbstractEarlyWarningSystem): 85 name = "gtk-ews" 86 port_name = "gtk" 87 watchers = AbstractEarlyWarningSystem.watchers + [ 88 "gns@gnome.org", 89 "xan.lopez@gmail.com", 90 ] 91 92 93class QtEWS(AbstractEarlyWarningSystem): 94 name = "qt-ews" 95 port_name = "qt" 96 97 98class ChromiumEWS(AbstractEarlyWarningSystem): 99 name = "chromium-ews" 100 port_name = "chromium" 101 watchers = AbstractEarlyWarningSystem.watchers + [ 102 "dglazkov@chromium.org", 103 ] 104 105 106# For platforms that we can't run inside a VM (like Mac OS X), we require 107# patches to be uploaded by committers, who are generally trustworthy folk. :) 108class AbstractCommitterOnlyEWS(AbstractEarlyWarningSystem): 109 def __init__(self, committers=CommitterList()): 110 AbstractEarlyWarningSystem.__init__(self) 111 self._committers = committers 112 113 def process_work_item(self, patch): 114 if not self._committers.committer_by_email(patch.attacher_email()): 115 self._did_error(patch, "%s cannot process patches from non-committers :(" % self.name) 116 return 117 AbstractEarlyWarningSystem.process_work_item(self, patch) 118 119 120class MacEWS(AbstractCommitterOnlyEWS): 121 name = "mac-ews" 122 port_name = "mac" 123