[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.17-1283-gcf603cf
eric at webkit.org
eric at webkit.org
Wed Jan 6 00:11:11 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit 05f65611acd7e772b8d77e6983d4b019d2e60b23
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Dec 30 04:47:56 2009 +0000
2009-12-29 Eric Seidel <eric at webkit.org>
Reviewed by Adam Barth.
Need a script to assign bugs with r+ patches to committers for landing
https://bugs.webkit.org/show_bug.cgi?id=33009
This is just one more small tool to help in the fight against our
ever-growing list of to-be-committed patches.
* Scripts/modules/bugzilla.py:
- Rename assign_to_email to assigned_to_email (typo).
- Add assigned_to_email() method on Bug.
- Add reassign_bug method.
- Add Bugzilla.unassigned_email, eventually should move to some webkit_config.py module.
* Scripts/modules/bugzilla_unittest.py:
- Update test after assigned_to_email rename.
* Scripts/modules/commands/commandtest.py:
- Call bind_to_tool to that self.tool works in Command testing.
* Scripts/modules/commands/download.py:
- Move AbstractDeclarativeCommmand multicommandtool.py, it should be part of Command.
* Scripts/modules/commands/queries_unittest.py:
- One of the test patches is now posted by "eric at webkit.org" which is a committer.
- Eventually we'll mock out CommitterList and be able to better control what's a committer and what's not.
* Scripts/modules/commands/upload.py:
- Add new assign-to-committer command.
* Scripts/modules/commands/upload_unittest.py:
- Add basic assign-to-committer test.
* Scripts/modules/committers.py:
- Add bugzilla_email() accessor.
* Scripts/modules/committers_unittest.py:
- Test our assumption that bugzilla_email is the first email.
* Scripts/modules/mock_bugzillatool.py:
- Add _id_to_object_dictionary for generating bug_cache from list of bugs.
- Remove unused fetch_attachments_from_bug.
- Add fetch_bug support and a bug_cache.
* Scripts/modules/multicommandtool.py:
- Move AbstractDeclarativeCommmand here from download.py
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52641 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index 682f33f..03b092e 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,42 @@
+2009-12-29 Eric Seidel <eric at webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Need a script to assign bugs with r+ patches to committers for landing
+ https://bugs.webkit.org/show_bug.cgi?id=33009
+
+ This is just one more small tool to help in the fight against our
+ ever-growing list of to-be-committed patches.
+
+ * Scripts/modules/bugzilla.py:
+ - Rename assign_to_email to assigned_to_email (typo).
+ - Add assigned_to_email() method on Bug.
+ - Add reassign_bug method.
+ - Add Bugzilla.unassigned_email, eventually should move to some webkit_config.py module.
+ * Scripts/modules/bugzilla_unittest.py:
+ - Update test after assigned_to_email rename.
+ * Scripts/modules/commands/commandtest.py:
+ - Call bind_to_tool to that self.tool works in Command testing.
+ * Scripts/modules/commands/download.py:
+ - Move AbstractDeclarativeCommmand multicommandtool.py, it should be part of Command.
+ * Scripts/modules/commands/queries_unittest.py:
+ - One of the test patches is now posted by "eric at webkit.org" which is a committer.
+ - Eventually we'll mock out CommitterList and be able to better control what's a committer and what's not.
+ * Scripts/modules/commands/upload.py:
+ - Add new assign-to-committer command.
+ * Scripts/modules/commands/upload_unittest.py:
+ - Add basic assign-to-committer test.
+ * Scripts/modules/committers.py:
+ - Add bugzilla_email() accessor.
+ * Scripts/modules/committers_unittest.py:
+ - Test our assumption that bugzilla_email is the first email.
+ * Scripts/modules/mock_bugzillatool.py:
+ - Add _id_to_object_dictionary for generating bug_cache from list of bugs.
+ - Remove unused fetch_attachments_from_bug.
+ - Add fetch_bug support and a bug_cache.
+ * Scripts/modules/multicommandtool.py:
+ - Move AbstractDeclarativeCommmand here from download.py
+
2009-12-29 Adam Barth <abarth at webkit.org>
Reviewed by Eric Seidel.
diff --git a/WebKitTools/Scripts/modules/bugzilla.py b/WebKitTools/Scripts/modules/bugzilla.py
index 3d895f3..7729813 100644
--- a/WebKitTools/Scripts/modules/bugzilla.py
+++ b/WebKitTools/Scripts/modules/bugzilla.py
@@ -69,6 +69,9 @@ class Bug(object):
def __init__(self, bug_dictionary):
self.bug_dictionary = bug_dictionary
+ def assigned_to_email(self):
+ return self.bug_dictionary["assigned_to_email"]
+
# Rarely do we actually want obsolete attachments
def attachments(self, include_obsolete=False):
if include_obsolete:
@@ -93,10 +96,11 @@ class Bugzilla(object):
self.browser.set_handle_robots(False)
self.committers = committers
- # Defaults (until we support better option parsing):
+ # FIXME: Much of this should go into some sort of config module:
bug_server_host = "bugs.webkit.org"
bug_server_regex = "https?://%s/" % re.sub('\.', '\\.', bug_server_host)
bug_server_url = "https://%s/" % bug_server_host
+ unassigned_email = "webkit-unassigned at lists.webkit.org"
def bug_url_for_bug_id(self, bug_id, xml=False):
content_type = "&ctype=xml" if xml else ""
@@ -138,7 +142,7 @@ class Bugzilla(object):
bug["id"] = int(soup.find("bug_id").string)
bug["title"] = unicode(soup.find("short_desc").string)
bug["reporter_email"] = str(soup.find("reporter").string)
- bug["assign_to_email"] = str(soup.find("assigned_to").string)
+ bug["assigned_to_email"] = str(soup.find("assigned_to").string)
bug["cc_emails"] = [str(element.string) for element in soup.findAll('cc')]
bug["attachments"] = [self._parse_attachment_element(element, bug["id"]) for element in soup.findAll('attachment')]
return bug
@@ -516,6 +520,22 @@ class Bugzilla(object):
self.browser['resolution'] = ['FIXED']
self.browser.submit()
+ def reassign_bug(self, bug_id, assignee, comment_text=None):
+ self.authenticate()
+
+ log("Assigning bug %s to %s" % (bug_id, assignee))
+ if self.dryrun:
+ log(comment_text)
+ return
+
+ self.browser.open(self.bug_url_for_bug_id(bug_id))
+ self.browser.select_form(name="changeform")
+ if comment_text:
+ log(comment_text)
+ self.browser["comment"] = comment_text
+ self.browser["assigned_to"] = assignee
+ self.browser.submit()
+
def reopen_bug(self, bug_id, comment_text):
self.authenticate()
diff --git a/WebKitTools/Scripts/modules/bugzilla_unittest.py b/WebKitTools/Scripts/modules/bugzilla_unittest.py
index 59480dc..427a7b8 100644
--- a/WebKitTools/Scripts/modules/bugzilla_unittest.py
+++ b/WebKitTools/Scripts/modules/bugzilla_unittest.py
@@ -174,7 +174,7 @@ ZEZpbmlzaExvYWRXaXRoUmVhc29uOnJlYXNvbl07Cit9CisKIEBlbmQKIAogI2VuZGlmCg==
"title" : u"bug to test bugzilla-tool and commit-queue failures",
"cc_emails" : ["foo at bar.com", "example at example.com"],
"reporter_email" : "eric at webkit.org",
- "assign_to_email" : "webkit-unassigned at lists.webkit.org",
+ "assigned_to_email" : "webkit-unassigned at lists.webkit.org",
"attachments" : [{
'name': u'Patch',
'url': 'https://bugs.webkit.org/attachment.cgi?id=45548',
diff --git a/WebKitTools/Scripts/modules/commands/commandtest.py b/WebKitTools/Scripts/modules/commands/commandtest.py
index 9384224..e6ba4f7 100644
--- a/WebKitTools/Scripts/modules/commands/commandtest.py
+++ b/WebKitTools/Scripts/modules/commands/commandtest.py
@@ -34,4 +34,5 @@ from modules.outputcapture import OutputCapture
class CommandsTest(unittest.TestCase):
def assert_execute_outputs(self, command, args, expected_stdout="", expected_stderr="", options=Mock(), tool=MockBugzillaTool()):
+ command.bind_to_tool(tool)
OutputCapture().assert_outputs(self, command.execute, [options, args, tool], expected_stdout=expected_stdout, expected_stderr=expected_stderr)
diff --git a/WebKitTools/Scripts/modules/commands/download.py b/WebKitTools/Scripts/modules/commands/download.py
index 4d0ccc5..b52c85e 100644
--- a/WebKitTools/Scripts/modules/commands/download.py
+++ b/WebKitTools/Scripts/modules/commands/download.py
@@ -40,19 +40,11 @@ from modules.comments import bug_comment_from_commit_text
from modules.executive import ScriptError
from modules.grammar import pluralize
from modules.logging import error, log
-from modules.multicommandtool import Command
+from modules.multicommandtool import AbstractDeclarativeCommmand, Command
from modules.stepsequence import StepSequence
# FIXME: Move this to a more general location.
-class AbstractDeclarativeCommmand(Command):
- help_text = None
- argument_names = None
- def __init__(self, options):
- Command.__init__(self, self.help_text, self.argument_names, options)
-
-
-# FIXME: Move this to a more general location.
class AbstractSequencedCommmand(AbstractDeclarativeCommmand):
steps = None
def __init__(self):
diff --git a/WebKitTools/Scripts/modules/commands/queries_unittest.py b/WebKitTools/Scripts/modules/commands/queries_unittest.py
index 0d1c82a..aa5f7f1 100644
--- a/WebKitTools/Scripts/modules/commands/queries_unittest.py
+++ b/WebKitTools/Scripts/modules/commands/queries_unittest.py
@@ -44,8 +44,8 @@ class QueryCommandsTest(CommandsTest):
self.assert_execute_outputs(PatchesToCommit(), None, expected_stdout, expected_stderr)
def test_patches_to_commit_queue(self):
- expected_stdout = "http://example.com/197&action=edit\nhttp://example.com/128&action=edit\n"
- expected_stderr = ""
+ expected_stdout = "http://example.com/197&action=edit\n"
+ expected_stderr = "128 committer = \"Eric Seidel\" <eric at webkit.org>\n"
options = Mock()
options.bugs = False
self.assert_execute_outputs(PatchesToCommitQueue(), None, expected_stdout, expected_stderr, options=options)
diff --git a/WebKitTools/Scripts/modules/commands/upload.py b/WebKitTools/Scripts/modules/commands/upload.py
index 3432f26..fc65c5b 100644
--- a/WebKitTools/Scripts/modules/commands/upload.py
+++ b/WebKitTools/Scripts/modules/commands/upload.py
@@ -39,9 +39,10 @@ from modules.bugzilla import parse_bug_id
from modules.buildsteps import PrepareChangeLogStep, EditChangeLogStep, ConfirmDiffStep, CommandOptions, ObsoletePatchesOnBugStep, PostDiffToBugStep, PromptForBugOrTitleStep, CreateBugStep
from modules.commands.download import AbstractSequencedCommmand
from modules.comments import bug_comment_from_svn_revision
+from modules.committers import CommitterList
from modules.grammar import pluralize
from modules.logging import error, log
-from modules.multicommandtool import Command
+from modules.multicommandtool import Command, AbstractDeclarativeCommmand
# FIXME: Requires unit test.
class CommitMessageForCurrentDiff(Command):
@@ -54,6 +55,38 @@ class CommitMessageForCurrentDiff(Command):
print "%s" % tool.scm().commit_message_for_this_commit().message()
+class AssignToCommitter(AbstractDeclarativeCommmand):
+ name = "assign-to-committer"
+ help_text = "Assign bug to whoever attached the most recent r+'d patch"
+
+ def _assign_bug_to_last_patch_attacher(self, bug_id):
+ committers = CommitterList()
+ bug = self.tool.bugs.fetch_bug(bug_id)
+ assigned_to_email = bug.assigned_to_email()
+ if assigned_to_email != self.tool.bugs.unassigned_email:
+ log("Bug %s is already assigned to %s (%s)." % (bug_id, assigned_to_email, committers.committer_by_email(assigned_to_email)))
+ return
+
+ # FIXME: This should call a reviewed_patches() method on bug instead of re-fetching.
+ reviewed_patches = self.tool.bugs.fetch_reviewed_patches_from_bug(bug_id)
+ if not reviewed_patches:
+ log("Bug %s has no non-obsolete patches, ignoring." % bug_id)
+ return
+ latest_patch = reviewed_patches[-1]
+ attacher_email = latest_patch["attacher_email"]
+ committer = committers.committer_by_email(attacher_email)
+ if not committer:
+ log("Attacher %s is not a committer. Bug %s likely needs commit-queue+." % (attacher_email, bug_id))
+ return
+
+ reassign_message = "Attachment %s was posted by a committer and has review+, assigning to %s for commit." % (latest_patch["id"], committer.full_name)
+ self.tool.bugs.reassign_bug(bug_id, committer.bugzilla_email(), reassign_message)
+
+ def execute(self, options, args, tool):
+ for bug_id in tool.bugs.fetch_bug_ids_from_needs_commit_list():
+ self._assign_bug_to_last_patch_attacher(bug_id)
+
+
class ObsoleteAttachments(AbstractSequencedCommmand):
name = "obsolete-attachments"
help_text = "Mark all attachments on a bug as obsolete"
diff --git a/WebKitTools/Scripts/modules/commands/upload_unittest.py b/WebKitTools/Scripts/modules/commands/upload_unittest.py
index 77177be..bf10740 100644
--- a/WebKitTools/Scripts/modules/commands/upload_unittest.py
+++ b/WebKitTools/Scripts/modules/commands/upload_unittest.py
@@ -30,8 +30,15 @@ import unittest
from modules.commands.commandtest import CommandsTest
from modules.commands.upload import *
+from modules.mock_bugzillatool import MockBugzillaTool
class UploadCommandsTest(CommandsTest):
+ def test_assign_to_committer(self):
+ tool = MockBugzillaTool()
+ expected_stderr = "Bug 75 is already assigned to foo at foo.com (None).\nBug 76 has no non-obsolete patches, ignoring.\n"
+ self.assert_execute_outputs(AssignToCommitter(), [], expected_stderr=expected_stderr, tool=tool)
+ tool.bugs.reassign_bug.assert_called_with(42, "eric at webkit.org", "Attachment 128 was posted by a committer and has review+, assigning to Eric Seidel for commit.")
+
def test_obsolete_attachments(self):
expected_stderr = "Obsoleting 2 old patches on bug 42\n"
self.assert_execute_outputs(ObsoleteAttachments(), [42], expected_stderr=expected_stderr)
diff --git a/WebKitTools/Scripts/modules/committers.py b/WebKitTools/Scripts/modules/committers.py
index 3f16b11..8d111a9 100644
--- a/WebKitTools/Scripts/modules/committers.py
+++ b/WebKitTools/Scripts/modules/committers.py
@@ -37,6 +37,10 @@ class Committer:
self.emails = email_or_emails
self.can_review = False
+ # FIXME: We're assuming the first email is a valid bugzilla email, which might not be right.
+ def bugzilla_email(self):
+ return self.emails[0]
+
def __str__(self):
return '"%s" <%s>' % (self.full_name, self.emails[0])
diff --git a/WebKitTools/Scripts/modules/committers_unittest.py b/WebKitTools/Scripts/modules/committers_unittest.py
index cf9f486..f5dc539 100644
--- a/WebKitTools/Scripts/modules/committers_unittest.py
+++ b/WebKitTools/Scripts/modules/committers_unittest.py
@@ -43,6 +43,9 @@ class CommittersTest(unittest.TestCase):
self.assertEqual(committer_list.committer_by_email('two at rad.com'), reviewer)
self.assertEqual(committer_list.reviewer_by_email('so_two at gmail.com'), reviewer)
+ # Test that the first email is assumed to be the Bugzilla email address (for now)
+ self.assertEqual(committer_list.committer_by_email('two at rad.com').bugzilla_email(), 'two at test.com')
+
# Test that a known committer is not returned during reviewer lookup
self.assertEqual(committer_list.reviewer_by_email('one at test.com'), None)
diff --git a/WebKitTools/Scripts/modules/mock_bugzillatool.py b/WebKitTools/Scripts/modules/mock_bugzillatool.py
index 0f396d0..6f79685 100644
--- a/WebKitTools/Scripts/modules/mock_bugzillatool.py
+++ b/WebKitTools/Scripts/modules/mock_bugzillatool.py
@@ -30,7 +30,13 @@ import os
from modules.mock import Mock
from modules.scm import CommitMessage
+from modules.bugzilla import Bug
+def _id_to_object_dictionary(objects):
+ dictionary = {}
+ for thing in objects:
+ dictionary[thing["id"]] = thing
+ return dictionary
class MockBugzilla(Mock):
patch1 = {
@@ -47,9 +53,10 @@ class MockBugzilla(Mock):
"url" : "http://example.com/128",
"is_obsolete" : False,
"reviewer" : "Reviewer2",
- "attacher_email" : "Contributer2",
+ "attacher_email" : "eric at webkit.org",
}
bug_server_url = "http://example.com"
+ unassigned_email = "unassigned at example.com"
def fetch_bug_ids_from_commit_queue(self):
return [42, 75]
@@ -60,6 +67,30 @@ class MockBugzilla(Mock):
def fetch_patches_from_commit_queue(self, reject_invalid_patches=False):
return [self.patch1, self.patch2]
+ def fetch_bug_ids_from_needs_commit_list(self):
+ return [42, 75, 76]
+
+ bug1 = {
+ "id" : 42,
+ "assigned_to_email" : unassigned_email,
+ "attachments" : [patch1, patch2],
+ }
+ bug2 = {
+ "id" : 75,
+ "assigned_to_email" : "foo at foo.com",
+ "attachments" : [],
+ }
+ bug3 = {
+ "id" : 76,
+ "assigned_to_email" : unassigned_email,
+ "attachments" : [],
+ }
+
+ bug_cache = _id_to_object_dictionary([bug1, bug2, bug3])
+
+ def fetch_bug(self, bug_id):
+ return Bug(self.bug_cache.get(bug_id))
+
def fetch_patches_from_pending_commit_list(self):
return [self.patch1, self.patch2]
@@ -68,11 +99,6 @@ class MockBugzilla(Mock):
return [self.patch1, self.patch2]
return []
- def fetch_attachments_from_bug(self, bug_id):
- if bug_id == 42:
- return [self.patch1, self.patch2]
- return None
-
def fetch_patches_from_bug(self, bug_id):
if bug_id == 42:
return [self.patch1, self.patch2]
diff --git a/WebKitTools/Scripts/modules/multicommandtool.py b/WebKitTools/Scripts/modules/multicommandtool.py
index 50bd11c..8d2c395 100644
--- a/WebKitTools/Scripts/modules/multicommandtool.py
+++ b/WebKitTools/Scripts/modules/multicommandtool.py
@@ -38,6 +38,7 @@ from optparse import OptionParser, IndentedHelpFormatter, SUPPRESS_USAGE, make_o
from modules.grammar import pluralize
from modules.logging import log
+
class Command(object):
name = None
show_in_main_help = False
@@ -125,6 +126,15 @@ class Command(object):
# Some commands might require a dummy tool
return self.check_arguments_and_execute(options, args)
+
+# FIXME: This should just be rolled into Command. help_text and argument_names do not need to be instance variables.
+class AbstractDeclarativeCommmand(Command):
+ help_text = None
+ argument_names = None
+ def __init__(self, options=None):
+ Command.__init__(self, self.help_text, self.argument_names, options)
+
+
class HelpPrintingOptionParser(OptionParser):
def __init__(self, epilog_method=None, *args, **kwargs):
self.epilog_method = epilog_method
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list