Changeset 52641 in webkit
- Timestamp:
- Dec 29, 2009 8:47:56 PM (14 years ago)
- Location:
- trunk/WebKitTools
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKitTools/ChangeLog
r52640 r52641 1 2009-12-29 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Adam Barth. 4 5 Need a script to assign bugs with r+ patches to committers for landing 6 https://bugs.webkit.org/show_bug.cgi?id=33009 7 8 This is just one more small tool to help in the fight against our 9 ever-growing list of to-be-committed patches. 10 11 * Scripts/modules/bugzilla.py: 12 - Rename assign_to_email to assigned_to_email (typo). 13 - Add assigned_to_email() method on Bug. 14 - Add reassign_bug method. 15 - Add Bugzilla.unassigned_email, eventually should move to some webkit_config.py module. 16 * Scripts/modules/bugzilla_unittest.py: 17 - Update test after assigned_to_email rename. 18 * Scripts/modules/commands/commandtest.py: 19 - Call bind_to_tool to that self.tool works in Command testing. 20 * Scripts/modules/commands/download.py: 21 - Move AbstractDeclarativeCommmand multicommandtool.py, it should be part of Command. 22 * Scripts/modules/commands/queries_unittest.py: 23 - One of the test patches is now posted by "eric@webkit.org" which is a committer. 24 - Eventually we'll mock out CommitterList and be able to better control what's a committer and what's not. 25 * Scripts/modules/commands/upload.py: 26 - Add new assign-to-committer command. 27 * Scripts/modules/commands/upload_unittest.py: 28 - Add basic assign-to-committer test. 29 * Scripts/modules/committers.py: 30 - Add bugzilla_email() accessor. 31 * Scripts/modules/committers_unittest.py: 32 - Test our assumption that bugzilla_email is the first email. 33 * Scripts/modules/mock_bugzillatool.py: 34 - Add _id_to_object_dictionary for generating bug_cache from list of bugs. 35 - Remove unused fetch_attachments_from_bug. 36 - Add fetch_bug support and a bug_cache. 37 * Scripts/modules/multicommandtool.py: 38 - Move AbstractDeclarativeCommmand here from download.py 39 1 40 2009-12-29 Adam Barth <abarth@webkit.org> 2 41 -
trunk/WebKitTools/Scripts/modules/bugzilla.py
r52628 r52641 70 70 self.bug_dictionary = bug_dictionary 71 71 72 def assigned_to_email(self): 73 return self.bug_dictionary["assigned_to_email"] 74 72 75 # Rarely do we actually want obsolete attachments 73 76 def attachments(self, include_obsolete=False): … … 94 97 self.committers = committers 95 98 96 # Defaults (until we support better option parsing):99 # FIXME: Much of this should go into some sort of config module: 97 100 bug_server_host = "bugs.webkit.org" 98 101 bug_server_regex = "https?://%s/" % re.sub('\.', '\\.', bug_server_host) 99 102 bug_server_url = "https://%s/" % bug_server_host 103 unassigned_email = "webkit-unassigned@lists.webkit.org" 100 104 101 105 def bug_url_for_bug_id(self, bug_id, xml=False): … … 139 143 bug["title"] = unicode(soup.find("short_desc").string) 140 144 bug["reporter_email"] = str(soup.find("reporter").string) 141 bug["assign _to_email"] = str(soup.find("assigned_to").string)145 bug["assigned_to_email"] = str(soup.find("assigned_to").string) 142 146 bug["cc_emails"] = [str(element.string) for element in soup.findAll('cc')] 143 147 bug["attachments"] = [self._parse_attachment_element(element, bug["id"]) for element in soup.findAll('attachment')] … … 517 521 self.browser.submit() 518 522 523 def reassign_bug(self, bug_id, assignee, comment_text=None): 524 self.authenticate() 525 526 log("Assigning bug %s to %s" % (bug_id, assignee)) 527 if self.dryrun: 528 log(comment_text) 529 return 530 531 self.browser.open(self.bug_url_for_bug_id(bug_id)) 532 self.browser.select_form(name="changeform") 533 if comment_text: 534 log(comment_text) 535 self.browser["comment"] = comment_text 536 self.browser["assigned_to"] = assignee 537 self.browser.submit() 538 519 539 def reopen_bug(self, bug_id, comment_text): 520 540 self.authenticate() -
trunk/WebKitTools/Scripts/modules/bugzilla_unittest.py
r52628 r52641 175 175 "cc_emails" : ["foo@bar.com", "example@example.com"], 176 176 "reporter_email" : "eric@webkit.org", 177 "assign _to_email" : "webkit-unassigned@lists.webkit.org",177 "assigned_to_email" : "webkit-unassigned@lists.webkit.org", 178 178 "attachments" : [{ 179 179 'name': u'Patch', -
trunk/WebKitTools/Scripts/modules/commands/commandtest.py
r52239 r52641 35 35 class CommandsTest(unittest.TestCase): 36 36 def assert_execute_outputs(self, command, args, expected_stdout="", expected_stderr="", options=Mock(), tool=MockBugzillaTool()): 37 command.bind_to_tool(tool) 37 38 OutputCapture().assert_outputs(self, command.execute, [options, args, tool], expected_stdout=expected_stdout, expected_stderr=expected_stderr) -
trunk/WebKitTools/Scripts/modules/commands/download.py
r52628 r52641 41 41 from modules.grammar import pluralize 42 42 from modules.logging import error, log 43 from modules.multicommandtool import Command43 from modules.multicommandtool import AbstractDeclarativeCommmand, Command 44 44 from modules.stepsequence import StepSequence 45 46 47 # FIXME: Move this to a more general location.48 class AbstractDeclarativeCommmand(Command):49 help_text = None50 argument_names = None51 def __init__(self, options):52 Command.__init__(self, self.help_text, self.argument_names, options)53 45 54 46 -
trunk/WebKitTools/Scripts/modules/commands/queries_unittest.py
r51959 r52641 45 45 46 46 def test_patches_to_commit_queue(self): 47 expected_stdout = "http://example.com/197&action=edit\n http://example.com/128&action=edit\n"48 expected_stderr = " "47 expected_stdout = "http://example.com/197&action=edit\n" 48 expected_stderr = "128 committer = \"Eric Seidel\" <eric@webkit.org>\n" 49 49 options = Mock() 50 50 options.bugs = False -
trunk/WebKitTools/Scripts/modules/commands/upload.py
r52628 r52641 40 40 from modules.commands.download import AbstractSequencedCommmand 41 41 from modules.comments import bug_comment_from_svn_revision 42 from modules.committers import CommitterList 42 43 from modules.grammar import pluralize 43 44 from modules.logging import error, log 44 from modules.multicommandtool import Command 45 from modules.multicommandtool import Command, AbstractDeclarativeCommmand 45 46 46 47 # FIXME: Requires unit test. … … 53 54 os.chdir(tool.scm().checkout_root) 54 55 print "%s" % tool.scm().commit_message_for_this_commit().message() 56 57 58 class AssignToCommitter(AbstractDeclarativeCommmand): 59 name = "assign-to-committer" 60 help_text = "Assign bug to whoever attached the most recent r+'d patch" 61 62 def _assign_bug_to_last_patch_attacher(self, bug_id): 63 committers = CommitterList() 64 bug = self.tool.bugs.fetch_bug(bug_id) 65 assigned_to_email = bug.assigned_to_email() 66 if assigned_to_email != self.tool.bugs.unassigned_email: 67 log("Bug %s is already assigned to %s (%s)." % (bug_id, assigned_to_email, committers.committer_by_email(assigned_to_email))) 68 return 69 70 # FIXME: This should call a reviewed_patches() method on bug instead of re-fetching. 71 reviewed_patches = self.tool.bugs.fetch_reviewed_patches_from_bug(bug_id) 72 if not reviewed_patches: 73 log("Bug %s has no non-obsolete patches, ignoring." % bug_id) 74 return 75 latest_patch = reviewed_patches[-1] 76 attacher_email = latest_patch["attacher_email"] 77 committer = committers.committer_by_email(attacher_email) 78 if not committer: 79 log("Attacher %s is not a committer. Bug %s likely needs commit-queue+." % (attacher_email, bug_id)) 80 return 81 82 reassign_message = "Attachment %s was posted by a committer and has review+, assigning to %s for commit." % (latest_patch["id"], committer.full_name) 83 self.tool.bugs.reassign_bug(bug_id, committer.bugzilla_email(), reassign_message) 84 85 def execute(self, options, args, tool): 86 for bug_id in tool.bugs.fetch_bug_ids_from_needs_commit_list(): 87 self._assign_bug_to_last_patch_attacher(bug_id) 55 88 56 89 -
trunk/WebKitTools/Scripts/modules/commands/upload_unittest.py
r52600 r52641 31 31 from modules.commands.commandtest import CommandsTest 32 32 from modules.commands.upload import * 33 from modules.mock_bugzillatool import MockBugzillaTool 33 34 34 35 class UploadCommandsTest(CommandsTest): 36 def test_assign_to_committer(self): 37 tool = MockBugzillaTool() 38 expected_stderr = "Bug 75 is already assigned to foo@foo.com (None).\nBug 76 has no non-obsolete patches, ignoring.\n" 39 self.assert_execute_outputs(AssignToCommitter(), [], expected_stderr=expected_stderr, tool=tool) 40 tool.bugs.reassign_bug.assert_called_with(42, "eric@webkit.org", "Attachment 128 was posted by a committer and has review+, assigning to Eric Seidel for commit.") 41 35 42 def test_obsolete_attachments(self): 36 43 expected_stderr = "Obsoleting 2 old patches on bug 42\n" -
trunk/WebKitTools/Scripts/modules/committers.py
r52604 r52641 37 37 self.emails = email_or_emails 38 38 self.can_review = False 39 40 # FIXME: We're assuming the first email is a valid bugzilla email, which might not be right. 41 def bugzilla_email(self): 42 return self.emails[0] 39 43 40 44 def __str__(self): -
trunk/WebKitTools/Scripts/modules/committers_unittest.py
r50505 r52641 44 44 self.assertEqual(committer_list.reviewer_by_email('so_two@gmail.com'), reviewer) 45 45 46 # Test that the first email is assumed to be the Bugzilla email address (for now) 47 self.assertEqual(committer_list.committer_by_email('two@rad.com').bugzilla_email(), 'two@test.com') 48 46 49 # Test that a known committer is not returned during reviewer lookup 47 50 self.assertEqual(committer_list.reviewer_by_email('one@test.com'), None) -
trunk/WebKitTools/Scripts/modules/mock_bugzillatool.py
r52599 r52641 31 31 from modules.mock import Mock 32 32 from modules.scm import CommitMessage 33 33 from modules.bugzilla import Bug 34 35 def _id_to_object_dictionary(objects): 36 dictionary = {} 37 for thing in objects: 38 dictionary[thing["id"]] = thing 39 return dictionary 34 40 35 41 class MockBugzilla(Mock): … … 48 54 "is_obsolete" : False, 49 55 "reviewer" : "Reviewer2", 50 "attacher_email" : " Contributer2",56 "attacher_email" : "eric@webkit.org", 51 57 } 52 58 bug_server_url = "http://example.com" 59 unassigned_email = "unassigned@example.com" 53 60 54 61 def fetch_bug_ids_from_commit_queue(self): … … 60 67 def fetch_patches_from_commit_queue(self, reject_invalid_patches=False): 61 68 return [self.patch1, self.patch2] 69 70 def fetch_bug_ids_from_needs_commit_list(self): 71 return [42, 75, 76] 72 73 bug1 = { 74 "id" : 42, 75 "assigned_to_email" : unassigned_email, 76 "attachments" : [patch1, patch2], 77 } 78 bug2 = { 79 "id" : 75, 80 "assigned_to_email" : "foo@foo.com", 81 "attachments" : [], 82 } 83 bug3 = { 84 "id" : 76, 85 "assigned_to_email" : unassigned_email, 86 "attachments" : [], 87 } 88 89 bug_cache = _id_to_object_dictionary([bug1, bug2, bug3]) 90 91 def fetch_bug(self, bug_id): 92 return Bug(self.bug_cache.get(bug_id)) 62 93 63 94 def fetch_patches_from_pending_commit_list(self): … … 68 99 return [self.patch1, self.patch2] 69 100 return [] 70 71 def fetch_attachments_from_bug(self, bug_id):72 if bug_id == 42:73 return [self.patch1, self.patch2]74 return None75 101 76 102 def fetch_patches_from_bug(self, bug_id): -
trunk/WebKitTools/Scripts/modules/multicommandtool.py
r52543 r52641 39 39 from modules.logging import log 40 40 41 41 42 class Command(object): 42 43 name = None … … 126 127 return self.check_arguments_and_execute(options, args) 127 128 129 130 # FIXME: This should just be rolled into Command. help_text and argument_names do not need to be instance variables. 131 class AbstractDeclarativeCommmand(Command): 132 help_text = None 133 argument_names = None 134 def __init__(self, options=None): 135 Command.__init__(self, self.help_text, self.argument_names, options) 136 137 128 138 class HelpPrintingOptionParser(OptionParser): 129 139 def __init__(self, epilog_method=None, *args, **kwargs):
Note: See TracChangeset
for help on using the changeset viewer.