[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

eric at webkit.org eric at webkit.org
Thu Apr 8 00:51:54 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit c9b643040688858a3d3347e58f05ce0db8a96dcd
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