Changeset 52480 in webkit
- Timestamp:
- Dec 21, 2009, 10:46:57 PM (16 years ago)
- Location:
- trunk/WebKitTools
- Files:
-
- 7 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKitTools/ChangeLog
r52457 r52480 1 2009-12-21 Adam Barth <abarth@webkit.org> 2 3 Reviewed by Eric Seidel. 4 5 [bzt] Automate the process of calling prepare-ChangeLog 6 https://bugs.webkit.org/show_bug.cgi?id=32816 7 8 This patch automates the process of creating a bug and patch and 9 uploading it to bugzilla. The first cut just calls 10 prepare-ChangeLog. 11 12 This patch required some refactoring of upload.py to the Step 13 model, but that's worth doing anyway. 14 15 * Scripts/bugzilla-tool: 16 * Scripts/modules/buildsteps.py: 17 * Scripts/modules/commands/download.py: 18 * Scripts/modules/commands/upload.py: 19 * Scripts/modules/commands/upload_unittest.py: 20 * Scripts/modules/mock_bugzillatool.py: 21 1 22 2009-12-21 Darin Adler <darin@apple.com> 2 23 -
trunk/WebKitTools/Scripts/bugzilla-tool
r52145 r52480 44 44 from modules.multicommandtool import MultiCommandTool 45 45 from modules.scm import detect_scm_system 46 from modules.user import User 47 46 48 47 49 class BugzillaTool(MultiCommandTool): … … 54 56 self.buildbot = BuildBot() 55 57 self.executive = Executive() 58 self.user = User() 56 59 self._scm = None 57 60 self.status_bot = StatusBot() -
trunk/WebKitTools/Scripts/modules/buildsteps.py
r52241 r52480 28 28 29 29 import os 30 import StringIO 30 31 31 32 from optparse import make_option … … 53 54 reviewer = make_option("-r", "--reviewer", action="store", type="string", dest="reviewer", help="Update ChangeLogs to say Reviewed by REVIEWER.") 54 55 complete_rollout = make_option("--complete-rollout", action="store_true", dest="complete_rollout", help="Commit the revert and re-open the original bug.") 56 obsolete_patches = make_option("--no-obsolete", action="store_false", dest="obsolete_patches", default=True, help="Do not obsolete old patches before posting this one.") 57 review = make_option("--no-review", action="store_false", dest="review", default=True, help="Do not mark the patch for review.") 58 request_commit = make_option("--request-commit", action="store_true", dest="request_commit", default=False, help="Mark the patch as needing auto-commit after review.") 59 description = make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: \"patch\")") 55 60 56 61 … … 63 68 def _run_script(self, script_name, quiet=False, port=WebKitPort): 64 69 log("Running %s" % script_name) 70 # FIXME: This should use self.port() 65 71 self._tool.executive.run_and_throw_if_fail(port.script_path(script_name), quiet) 66 72 … … 106 112 107 113 class PrepareChangelogStep(AbstractStep): 108 def run(self, state): 109 self._run_script("prepare-ChangeLog") 114 @classmethod 115 def options(cls): 116 return [ 117 CommandOptions.port, 118 CommandOptions.quiet, 119 CommandOptions.non_interactive, 120 ] 121 122 def run(self, state): 123 os.chdir(self._tool.scm().checkout_root) 124 args = [self.port().script_path("prepare-ChangeLog")] 125 if not self._options.non_interactive: 126 args.append("-o") 127 if state["bug_id"]: 128 args.append("--bug=%s" % state["bug_id"]) 129 self._tool.executive.run_and_throw_if_fail(args, self._options.quiet) 130 if not self._options.non_interactive: 131 self._tool.user.prompt("Press enter when ready to continue.") 132 133 134 class ObsoletePatchesOnBugStep(AbstractStep): 135 @classmethod 136 def options(cls): 137 return [ 138 CommandOptions.obsolete_patches, 139 ] 140 141 def run(self, state): 142 if not self._options.obsolete_patches: 143 return 144 bug_id = state["bug_id"] 145 patches = self._tool.bugs.fetch_patches_from_bug(bug_id) 146 if not patches: 147 return 148 log("Obsoleting %s on bug %s" % (pluralize("old patch", len(patches)), bug_id)) 149 for patch in patches: 150 self._tool.bugs.obsolete_attachment(patch["id"]) 151 152 153 class PostDiffToBugStep(AbstractStep): 154 @classmethod 155 def options(cls): 156 return [ 157 CommandOptions.description, 158 CommandOptions.review, 159 CommandOptions.request_commit, 160 ] 161 162 def run(self, state): 163 diff = self._tool.scm().create_patch() 164 diff_file = StringIO.StringIO(diff) # add_patch_to_bug expects a file-like object 165 description = self._options.description or "Patch" 166 self._tool.bugs.add_patch_to_bug(state["bug_id"], diff_file, description, mark_for_review=self._options.review, mark_for_commit_queue=self._options.request_commit) 110 167 111 168 -
trunk/WebKitTools/Scripts/modules/commands/download.py
r52295 r52480 53 53 54 54 55 # FIXME: Move this to a more general location. 55 56 class AbstractSequencedCommmand(AbstractDeclarativeCommmand): 56 57 steps = None -
trunk/WebKitTools/Scripts/modules/commands/upload.py
r52295 r52480 37 37 38 38 from modules.bugzilla import parse_bug_id 39 from modules.buildsteps import PrepareChangelogStep, CommandOptions, ObsoletePatchesOnBugStep, PostDiffToBugStep 40 from modules.commands.download import AbstractSequencedCommmand 39 41 from modules.comments import bug_comment_from_svn_revision 40 42 from modules.grammar import pluralize … … 53 55 54 56 55 class ObsoleteAttachments( Command):57 class ObsoleteAttachments(AbstractSequencedCommmand): 56 58 name = "obsolete-attachments" 57 def __init__(self): 58 Command.__init__(self, "Mark all attachments on a bug as obsolete", "BUGID") 59 60 def execute(self, options, args, tool): 61 bug_id = args[0] 62 attachments = tool.bugs.fetch_attachments_from_bug(bug_id) 63 for attachment in attachments: 64 if not attachment["is_obsolete"]: 65 tool.bugs.obsolete_attachment(attachment["id"]) 66 67 68 class PostDiff(Command): 59 help_text = "Mark all attachments on a bug as obsolete" 60 argument_names = "BUGID" 61 steps = [ 62 ObsoletePatchesOnBugStep, 63 ] 64 65 def _prepare_state(self, options, args, tool): 66 return { "bug_id" : args[0] } 67 68 69 class PostDiff(AbstractSequencedCommmand): 69 70 name = "post-diff" 71 help_text = "Attach the current working directory diff to a bug as a patch file" 72 argument_names = "[BUGID]" 70 73 show_in_main_help = True 71 def __init__(self): 72 options = [ 73 make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: \"patch\")"), 74 ] 75 options += self.posting_options() 76 Command.__init__(self, "Attach the current working directory diff to a bug as a patch file", "[BUGID]", options=options) 77 78 @staticmethod 79 def posting_options(): 80 return [ 81 make_option("--no-obsolete", action="store_false", dest="obsolete_patches", default=True, help="Do not obsolete old patches before posting this one."), 82 make_option("--no-review", action="store_false", dest="review", default=True, help="Do not mark the patch for review."), 83 make_option("--request-commit", action="store_true", dest="request_commit", default=False, help="Mark the patch as needing auto-commit after review."), 84 ] 85 86 @staticmethod 87 def obsolete_patches_on_bug(bug_id, bugs): 88 patches = bugs.fetch_patches_from_bug(bug_id) 89 if len(patches): 90 log("Obsoleting %s on bug %s" % (pluralize("old patch", len(patches)), bug_id)) 91 for patch in patches: 92 bugs.obsolete_attachment(patch["id"]) 93 94 def execute(self, options, args, tool): 74 steps = [ 75 ObsoletePatchesOnBugStep, 76 PostDiffToBugStep, 77 ] 78 79 def _prepare_state(self, options, args, tool): 95 80 # Perfer a bug id passed as an argument over a bug url in the diff (i.e. ChangeLogs). 96 81 bug_id = (args and args[0]) or parse_bug_id(tool.scm().create_patch()) 97 82 if not bug_id: 98 83 error("No bug id passed and no bug url found in diff, can't post.") 99 100 if options.obsolete_patches: 101 self.obsolete_patches_on_bug(bug_id, tool.bugs) 102 103 diff = tool.scm().create_patch() 104 diff_file = StringIO.StringIO(diff) # add_patch_to_bug expects a file-like object 105 106 description = options.description or "Patch" 107 tool.bugs.add_patch_to_bug(bug_id, diff_file, description, mark_for_review=options.review, mark_for_commit_queue=options.request_commit) 84 return { "bug_id" : bug_id } 85 86 87 class SubmitPatch(AbstractSequencedCommmand): 88 name = "submit-patch" 89 help_text = "Experimental. Creates a patch from the current working copy and uploads bugzilla" 90 argument_names = "BUGID" 91 steps = [ 92 PrepareChangelogStep, 93 # FIXME: Add a CreateBugStep! 94 ObsoletePatchesOnBugStep, 95 PostDiffToBugStep, 96 ] 97 98 def _prepare_state(self, options, args, tool): 99 bug_id = args[0] 100 return { "bug_id" : bug_id } 108 101 109 102 … … 116 109 make_option("--add-log-as-comment", action="store_true", dest="add_log_as_comment", default=False, help="Add commit log message as a comment when uploading the patch."), 117 110 make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: description from commit message)"), 111 CommandOptions.obsolete_patches, 112 CommandOptions.review, 113 CommandOptions.request_commit, 118 114 ] 119 options += PostDiff.posting_options()120 115 Command.__init__(self, "Attach a range of local commits to bugs as patch files", "COMMITISH", options=options, requires_local_commits=True) 121 116 … … 148 143 149 144 if options.obsolete_patches and bug_id not in have_obsoleted_patches: 150 PostDiff.obsolete_patches_on_bug(bug_id, tool.bugs) 145 state = { "bug_id": bug_id } 146 ObsoletePatchesOnBugStep(tool, options).run(state) 151 147 have_obsoleted_patches.add(bug_id) 152 148 -
trunk/WebKitTools/Scripts/modules/commands/upload_unittest.py
r52148 r52480 34 34 class UploadCommandsTest(CommandsTest): 35 35 def test_obsolete_attachments(self): 36 self.assert_execute_outputs(ObsoleteAttachments(), [42]) 36 expected_stderr = "Obsoleting 2 old patches on bug 42\n" 37 self.assert_execute_outputs(ObsoleteAttachments(), [42], expected_stderr=expected_stderr) 37 38 38 39 def test_post_diff(self): 39 40 expected_stderr = "Obsoleting 2 old patches on bug 42\n" 40 41 self.assert_execute_outputs(PostDiff(), [42], expected_stderr=expected_stderr) 42 43 def test_submit_patch(self): 44 expected_stderr = "Obsoleting 2 old patches on bug 42\n" 45 self.assert_execute_outputs(SubmitPatch(), [42], expected_stderr=expected_stderr) -
trunk/WebKitTools/Scripts/modules/mock_bugzillatool.py
r52430 r52480 109 109 return [] 110 110 111 111 112 class MockSCM(Mock): 112 113 def __init__(self): … … 143 144 144 145 146 class MockUser(object): 147 def prompt(self, message): 148 return "Mock user response" 149 150 145 151 class MockStatusBot(object): 146 152 def __init__(self): … … 159 165 self.buildbot = MockBuildBot() 160 166 self.executive = Mock() 167 self.user = MockUser() 161 168 self._scm = MockSCM() 162 169 self.status_bot = MockStatusBot() -
trunk/WebKitTools/Scripts/modules/user.py
r52479 r52480 1 # Copyright ( C) 2009Google Inc. All rights reserved.2 # 1 # Copyright (c) 2009, Google Inc. All rights reserved. 2 # 3 3 # Redistribution and use in source and binary forms, with or without 4 4 # modification, are permitted provided that the following conditions are 5 5 # met: 6 # 7 # * Redistributions of source code must retain the above copyright6 # 7 # * Redistributions of source code must retain the above copyright 8 8 # notice, this list of conditions and the following disclaimer. 9 # * Redistributions in binary form must reproduce the above9 # * Redistributions in binary form must reproduce the above 10 10 # copyright notice, this list of conditions and the following disclaimer 11 11 # in the documentation and/or other materials provided with the 12 12 # distribution. 13 # * Neither the name of Google Inc. nor the names of its13 # * Neither the name of Google Inc. nor the names of its 14 14 # contributors may be used to endorse or promote products derived from 15 15 # this software without specific prior written permission. 16 # 16 # 17 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT … … 27 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 28 29 import unittest 30 31 from modules.commands.commandtest import CommandsTest 32 from modules.commands.upload import * 33 34 class UploadCommandsTest(CommandsTest): 35 def test_obsolete_attachments(self): 36 self.assert_execute_outputs(ObsoleteAttachments(), [42]) 37 38 def test_post_diff(self): 39 expected_stderr = "Obsoleting 2 old patches on bug 42\n" 40 self.assert_execute_outputs(PostDiff(), [42], expected_stderr=expected_stderr) 29 class User(object): 30 def prompt(self, message): 31 return raw_input(message)
Note:
See TracChangeset
for help on using the changeset viewer.