Reviewed by Adam Barth.
Teach the StatusBot how to support more than just the commit-queue
https://bugs.webkit.org/show_bug.cgi?id=31754
* CommitQueueStatus/index.yaml:
- Add indices required for the new queries.
* CommitQueueStatus/queue_status.py:
- Add a patch-status page and move update_status to update-status.
- Only display "commit-queue" status records for the commit-queue.
- Add support for a queue_name property on status records.
- Fix _int_from_request to actually work.
* CommitQueueStatus/update_status.html:
- Add support for a queue_name on status records.
- Remove unused list of bug ids.
* Scripts/modules/commands/queues.py
- Make the queues pass the patch instead of the bug_id to StatusBot.
* Scripts/modules/statusbot.py:
- Support passing the queue_name to the status updates.
- Support fetching patch status with patch_status().
* Scripts/modules/workqueue.py:
- Pass the patch to the StatusBot instead of the bug_id.
- Let WorkQueues have a name.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@51264
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2009-11-20 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Teach the StatusBot how to support more than just the commit-queue
+ https://bugs.webkit.org/show_bug.cgi?id=31754
+
+ * CommitQueueStatus/index.yaml:
+ - Add indices required for the new queries.
+ * CommitQueueStatus/queue_status.py:
+ - Add a patch-status page and move update_status to update-status.
+ - Only display "commit-queue" status records for the commit-queue.
+ - Add support for a queue_name property on status records.
+ - Fix _int_from_request to actually work.
+ * CommitQueueStatus/update_status.html:
+ - Add support for a queue_name on status records.
+ - Remove unused list of bug ids.
+ * Scripts/modules/commands/queues.py
+ - Make the queues pass the patch instead of the bug_id to StatusBot.
+ * Scripts/modules/statusbot.py:
+ - Support passing the queue_name to the status updates.
+ - Support fetching patch status with patch_status().
+ * Scripts/modules/workqueue.py:
+ - Pass the patch to the StatusBot instead of the bug_id.
+ - Let WorkQueues have a name.
+
2009-11-20 Adam Barth <abarth@webkit.org>
Reviewed by Eric Seidel.
# manually, move them above the marker line. The index.yaml file is
# automatically uploaded to the admin console when you next deploy
# your application using appcfg.py.
+
+- kind: QueueStatus
+ properties:
+ - name: active_patch_id
+ - name: queue_name
+ - name: date
+ direction: desc
+
+- kind: QueueStatus
+ properties:
+ - name: queue_name
+ - name: date
+ direction: desc
webapp.template.register_template_library('filters.webkit_extras')
+
class QueueStatus(db.Model):
author = db.UserProperty()
+ queue_name = db.StringProperty()
active_bug_id = db.IntegerProperty()
active_patch_id = db.IntegerProperty()
message = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)
+
class MainPage(webapp.RequestHandler):
def get(self):
- statuses_query = QueueStatus.all().order('-date')
+ statuses_query = QueueStatus.all().filter('queue_name =', 'commit-queue').order('-date')
statuses = statuses_query.fetch(6)
+ if not statuses:
+ return self.response.out.write("No status to report.")
template_values = {
'last_status' : statuses[0],
'recent_statuses' : statuses[1:],
}
self.response.out.write(template.render('index.html', template_values))
+
+class PatchStatus(webapp.RequestHandler):
+ def get(self, queue_name, attachment_id):
+ statuses = QueueStatus.all().filter('queue_name =', queue_name).filter('active_patch_id =', attachment_id).order('-date')
+ if not statuses:
+ self.error(404)
+ self.response.out.write(statuses[0].message)
+
+
class UpdateStatus(webapp.RequestHandler):
def get(self):
self.response.out.write(template.render('update_status.html', None))
string_value = self.request.get(name)
try:
int_value = int(string_value)
+ return int_value
except ValueError, TypeError:
pass
return None
if users.get_current_user():
queue_status.author = users.get_current_user()
+ queue_name = self.request.get('queue_name')
+ queue_status.queue_name = queue_name
queue_status.active_bug_id = self._int_from_request('bug_id')
queue_status.active_patch_id = self._int_from_request('patch_id')
queue_status.message = self.request.get('status')
queue_status.put()
self.redirect('/')
+
routes = [
('/', MainPage),
- ('/update_status', UpdateStatus)
+ ('/update-status', UpdateStatus),
+ (r'/patch-status/(.*)/(.*)', PatchStatus),
]
application = webapp.WSGIApplication(routes, debug=True)
-Update the current status of the commit-queue:
<form name="update_status" method="post">
+Update status for a queue: <input name="queue_name">
<div>
Active Bug Id:
<input name="bug_id">
<div>
Active Patch Id:
<input name="patch_id">
- </div>
- <div>
- Space separated list of other bugs in queue:
- <input name="bugs_in_queue">
</div>
<div>
+ Status Text:<br>
<textarea name="status" rows="3" cols="60"></textarea>
</div>
<div><input type="submit" value="Add Status"></div>
def execute(self, options, args, tool):
self.options = options
self.tool = tool
- work_queue = WorkQueue(self)
+ work_queue = WorkQueue(self, self.name)
work_queue.run()
if red_builders_names:
red_builders_names = map(lambda name: "\"%s\"" % name, red_builders_names) # Add quotes around the names.
return (False, "Builders [%s] are red. See http://build.webkit.org." % ", ".join(red_builders_names), None)
- return (True, "Landing patch %s from bug %s." % (patch["id"], patch["bug_id"]), patch["bug_id"])
+ return (True, "Landing patch %s from bug %s." % (patch["id"], patch["bug_id"]), patch)
def process_work_item(self, patch):
self.run_bugzilla_tool(["land-attachment", "--force-clean", "--non-interactive", "--quiet", patch["id"]])
AbstractTryQueue.__init__(self)
def should_proceed_with_work_item(self, patch):
- return (True, "Checking style for patch %s on bug %s." % (patch["id"], patch["bug_id"]), patch["bug_id"])
+ return (True, "Checking style for patch %s on bug %s." % (patch["id"], patch["bug_id"]), patch)
def process_work_item(self, patch):
self.run_bugzilla_tool(["check-style", "--force-clean", patch["id"]])
self.run_bugzilla_tool(["build", self.port.flag(), "--force-clean", "--quiet"])
except ScriptError, e:
return (False, "Unable to perform a build.", None)
- return (True, "Building patch %s on bug %s." % (patch["id"], patch["bug_id"]), patch["bug_id"])
+ return (True, "Building patch %s on bug %s." % (patch["id"], patch["bug_id"]), patch)
def process_work_item(self, patch):
self.run_bugzilla_tool(["build-attachment", self.port.flag(), "--force-clean", "--quiet", "--no-update", patch["id"]])
"""
exit(1)
+import urllib2
+
+
class StatusBot:
default_host = "webkit-commit-queue.appspot.com"
def __init__(self, host=default_host):
self.statusbot_host = host
self.statusbot_server_url = "http://%s" % self.statusbot_host
- self.update_status_url = "%s/update_status" % self.statusbot_server_url
self.browser = Browser()
- def update_status(self, status, bug_id=None, patch_id=None):
+ def update_status(self, queue_name, status, patch):
# During unit testing, statusbot_host is None
if not self.statusbot_host:
return
- self.browser.open(self.update_status_url)
+
+ update_status_url = "%s/update-status" % self.statusbot_server_url
+ self.browser.open(update_status_url)
self.browser.select_form(name="update_status")
- if bug_id:
- self.browser['bug_id'] = str(bug_id)
- if patch_id:
- self.browser['patch_id'] = str(patch_id)
+ self.browser['queue_name'] = queue_name
+ if patch:
+ if patch.get('bug_id'):
+ self.browser['bug_id'] = str(patch['bug_id'])
+ if patch.get('id'):
+ self.browser['patch_id'] = str(patch['id'])
self.browser['status'] = status
self.browser.submit()
+
+ def patch_status(self, queue_name, patch_id):
+ update_status_url = "%s/patch-status/%s/%s" % (self.statusbot_server_url, queue_name, patch_id)
+ try:
+ return urllib2.urlopen(update_status_url).read()
+ except urllib2.HTTPError, e:
+ if e.code == 404:
+ return None
+ raise e
from modules.statusbot import StatusBot
class WorkQueueDelegate:
+ def queue_name(self):
+ raise NotImplementedError, "subclasses must implement"
+
def queue_log_path(self):
raise NotImplementedError, "subclasses must implement"
raise NotImplementedError, "subclasses must implement"
def should_proceed_with_work_item(self, work_item):
- # returns (safe_to_proceed, waiting_message, bug_id)
+ # returns (safe_to_proceed, waiting_message, patch)
raise NotImplementedError, "subclasses must implement"
def process_work_item(self, work_item):
class WorkQueue:
- def __init__(self, delegate):
+ def __init__(self, name, delegate):
+ self._name = name
self._delegate = delegate
self._output_tee = OutputTee()
if not work_item:
self._update_status_and_sleep("Empty queue.")
continue
- (safe_to_proceed, waiting_message, bug_id) = self._delegate.should_proceed_with_work_item(work_item)
+ (safe_to_proceed, waiting_message, patch) = self._delegate.should_proceed_with_work_item(work_item)
if not safe_to_proceed:
self._update_status_and_sleep(waiting_message)
continue
- self.status_bot.update_status(waiting_message, bug_id=bug_id)
+ self.status_bot.update_status(self._name, waiting_message, patch)
except Exception, e:
# Don't try tell the status bot, in case telling it causes an exception.
self._sleep("Exception while preparing queue: %s." % e)