Changeset 52129 in webkit
- Timestamp:
- Dec 14, 2009 9:21:33 PM (14 years ago)
- Location:
- trunk/WebKitTools
- Files:
-
- 1 deleted
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKitTools/ChangeLog
r52118 r52129 1 2009-12-14 Adam Barth <abarth@webkit.org> 2 3 Reviewed by Eric Seidel. 4 5 [bzt] Kill LandingSequence 6 https://bugs.webkit.org/show_bug.cgi?id=32464 7 8 Removes LandingSequence in favor of StepSequence. This required 9 changing the Step API slightly to carry a general notion of state 10 instead of carrying patches specifically. 11 12 * Scripts/modules/buildsteps.py: 13 * Scripts/modules/commands/download.py: 14 * Scripts/modules/commands/queues.py: 15 * Scripts/modules/landingsequence.py: Removed. 16 * Scripts/modules/stepsequence.py: 17 1 18 2009-12-14 Robert Hogan <robert@roberthogan.net> 2 19 -
trunk/WebKitTools/Scripts/modules/buildsteps.py
r51940 r52129 48 48 close_bug = make_option("--no-close", action="store_false", dest="close_bug", default=True, help="Leave bug open after landing.") 49 49 port = make_option("--port", action="store", dest="port", default=None, help="Specify a port (e.g., mac, qt, gtk, ...).") 50 reviewer = make_option("-r", "--reviewer", action="store", type="string", dest="reviewer", help="Update ChangeLogs to say Reviewed by REVIEWER.") 50 51 51 52 52 53 class AbstractStep(object): 53 def __init__(self, tool, options , patch=None):54 def __init__(self, tool, options): 54 55 self._tool = tool 55 56 self._options = options 56 self._patch = patch57 57 self._port = None 58 58 … … 72 72 return [] 73 73 74 def run(self, tool):74 def run(self, state): 75 75 raise NotImplementedError, "subclasses must implement" 76 76 77 77 78 78 class PrepareChangelogStep(AbstractStep): 79 def run(self ):79 def run(self, state): 80 80 self._run_script("prepare-ChangeLog") 81 81 82 82 83 83 class CleanWorkingDirectoryStep(AbstractStep): 84 def __init__(self, tool, options, patch=None,allow_local_commits=False):85 AbstractStep.__init__(self, tool, options , patch)84 def __init__(self, tool, options, allow_local_commits=False): 85 AbstractStep.__init__(self, tool, options) 86 86 self._allow_local_commits = allow_local_commits 87 87 … … 93 93 ] 94 94 95 def run(self ):95 def run(self, state): 96 96 os.chdir(self._tool.scm().checkout_root) 97 97 if not self._allow_local_commits: … … 109 109 ] 110 110 111 def run(self ):111 def run(self, state): 112 112 if not self._options.update: 113 113 return … … 123 123 ] 124 124 125 def run(self ):126 log("Processing patch %s from bug %s." % (s elf._patch["id"], self._patch["bug_id"]))127 self._tool.scm().apply_patch(s elf._patch, force=self._options.non_interactive)125 def run(self, state): 126 log("Processing patch %s from bug %s." % (state["patch"]["id"], state["patch"]["bug_id"])) 127 self._tool.scm().apply_patch(state["patch"], force=self._options.non_interactive) 128 128 129 129 … … 135 135 ] 136 136 137 def run(self ):137 def run(self, state): 138 138 if not self._options.check_builders: 139 139 return … … 145 145 146 146 147 class UpdateChangelogsWithReviewerStep(AbstractStep): 148 @classmethod 149 def options(cls): 150 return [ 151 CommandOptions.reviewer, 152 ] 153 154 def guess_reviewer_from_bug(self, bug_id): 155 patches = self._tool.bugs.fetch_reviewed_patches_from_bug(bug_id) 156 if len(patches) != 1: 157 log("%s on bug %s, cannot infer reviewer." % (pluralize("reviewed patch", len(patches)), bug_id)) 158 return None 159 patch = patches[0] 160 reviewer = patch["reviewer"] 161 log("Guessing \"%s\" as reviewer from attachment %s on bug %s." % (reviewer, patch["id"], bug_id)) 162 return reviewer 163 164 def run(self, state): 165 bug_id = state["patch"]["bug_id"] 166 reviewer = self._options.reviewer 167 if not reviewer: 168 if not bug_id: 169 log("No bug id provided and --reviewer= not provided. Not updating ChangeLogs with reviewer.") 170 return 171 reviewer = self.guess_reviewer_from_bug(bug_id) 172 173 if not reviewer: 174 log("Failed to guess reviewer from bug %s and --reviewer= not provided. Not updating ChangeLogs with reviewer." % bug_id) 175 return 176 177 os.chdir(self._tool.scm().checkout_root) 178 for changelog_path in self._tool.scm().modified_changelogs(): 179 ChangeLog(changelog_path).set_reviewer(reviewer) 180 181 147 182 class BuildStep(AbstractStep): 148 183 @classmethod … … 153 188 ] 154 189 155 def run(self ):190 def run(self, state): 156 191 if not self._options.build: 157 192 return … … 161 196 162 197 class CheckStyleStep(AbstractStep): 163 def run(self ):198 def run(self, state): 164 199 self._run_script("check-webkit-style") 165 200 … … 176 211 ] 177 212 178 def run(self ):213 def run(self, state): 179 214 if not self._options.build: 180 215 return … … 191 226 192 227 class CommitStep(AbstractStep): 193 def run(self ):228 def run(self, state): 194 229 commit_message = self._tool.scm().commit_message_for_this_commit() 195 returnself._tool.scm().commit_with_message(commit_message.message())230 state["commit_text"] = self._tool.scm().commit_with_message(commit_message.message()) 196 231 197 232 198 233 class ClosePatchStep(AbstractStep): 199 def run(self, commit_log):200 comment_text = bug_comment_from_commit_text(self._tool.scm(), commit_log)201 self._tool.bugs.clear_attachment_flags(s elf._patch["id"], comment_text)234 def run(self, state): 235 comment_text = bug_comment_from_commit_text(self._tool.scm(), state["commit_text"]) 236 self._tool.bugs.clear_attachment_flags(state["patch"]["id"], comment_text) 202 237 203 238 … … 209 244 ] 210 245 211 def run(self ):246 def run(self, state): 212 247 if not self._options.close_bug: 213 248 return 214 249 # Check to make sure there are no r? or r+ patches on the bug before closing. 215 250 # Assume that r- patches are just previous patches someone forgot to obsolete. 216 patches = self._tool.bugs.fetch_patches_from_bug(s elf._patch["bug_id"])251 patches = self._tool.bugs.fetch_patches_from_bug(state["patch"]["bug_id"]) 217 252 for patch in patches: 218 253 review_flag = patch.get("review") … … 220 255 log("Not closing bug %s as attachment %s has review=%s. Assuming there are more patches to land from this bug." % (patch["bug_id"], patch["id"], review_flag)) 221 256 return 222 self._tool.bugs.close_bug_as_fixed(self._patch["bug_id"], "All reviewed patches have been landed. Closing bug.") 257 self._tool.bugs.close_bug_as_fixed(state["patch"]["bug_id"], "All reviewed patches have been landed. Closing bug.") 258 259 260 class CloseBugForLandDiffStep(AbstractStep): 261 @classmethod 262 def options(cls): 263 return [ 264 CommandOptions.close_bug, 265 ] 266 267 def run(self, state): 268 comment_text = bug_comment_from_commit_text(self._tool.scm(), state["commit_text"]) 269 bug_id = state["patch"]["bug_id"] 270 if bug_id: 271 log("Updating bug %s" % bug_id) 272 if self._options.close_bug: 273 self._tool.bugs.close_bug_as_fixed(bug_id, comment_text) 274 else: 275 # FIXME: We should a smart way to figure out if the patch is attached 276 # to the bug, and if so obsolete it. 277 self._tool.bugs.post_comment_to_bug(bug_id, comment_text) 278 else: 279 log(comment_text) 280 log("No bug id provided.") 223 281 224 282 -
trunk/WebKitTools/Scripts/modules/commands/download.py
r51942 r52129 34 34 35 35 from modules.bugzilla import parse_bug_id 36 from modules.buildsteps import CommandOptions, BuildSteps, EnsureBuildersAreGreenStep, CleanWorkingDirectoryStep, UpdateStep, ApplyPatchStep, BuildStep, CheckStyleStep, PrepareChangelogStep 36 # FIXME: This list is rediculous. We need to learn the ways of __all__. 37 from modules.buildsteps import CommandOptions, BuildSteps, EnsureBuildersAreGreenStep, UpdateChangelogsWithReviewerStep, CleanWorkingDirectoryStep, UpdateStep, ApplyPatchStep, BuildStep, CheckStyleStep, RunTestsStep, CommitStep, ClosePatchStep, CloseBugStep, CloseBugForLandDiffStep, PrepareChangelogStep 37 38 from modules.changelogs import ChangeLog 38 39 from modules.comments import bug_comment_from_commit_text 39 40 from modules.executive import ScriptError 40 41 from modules.grammar import pluralize 41 from modules.landingsequence import LandingSequence42 42 from modules.logging import error, log 43 43 from modules.multicommandtool import Command … … 102 102 def setup_for_patch_apply(tool, options): 103 103 clean_step = CleanWorkingDirectoryStep(tool, options, allow_local_commits=True) 104 clean_step.run( )104 clean_step.run({}) 105 105 update_step = UpdateStep(tool, options) 106 update_step.run( )106 update_step.run({}) 107 107 108 108 @staticmethod … … 119 119 120 120 121 class LandDiffSequence(LandingSequence):122 def run(self):123 self.check_builders()124 self.build()125 self.test()126 commit_log = self.commit()127 self.close_bug(commit_log)128 129 def close_bug(self, commit_log):130 comment_test = bug_comment_from_commit_text(self._tool.scm(), commit_log)131 bug_id = self._patch["bug_id"]132 if bug_id:133 log("Updating bug %s" % bug_id)134 if self._options.close_bug:135 self._tool.bugs.close_bug_as_fixed(bug_id, comment_test)136 else:137 # FIXME: We should a smart way to figure out if the patch is attached138 # to the bug, and if so obsolete it.139 self._tool.bugs.post_comment_to_bug(bug_id, comment_test)140 else:141 log(comment_test)142 log("No bug id provided.")143 144 145 121 class LandDiff(Command): 146 122 name = "land-diff" 147 123 show_in_main_help = True 148 124 def __init__(self): 149 options = [ 150 make_option("-r", "--reviewer", action="store", type="string", dest="reviewer", help="Update ChangeLogs to say Reviewed by REVIEWER."), 151 ] 152 options += BuildSteps.build_options() 153 options += BuildSteps.land_options() 154 Command.__init__(self, "Land the current working directory diff and updates the associated bug if any", "[BUGID]", options=options) 155 156 def guess_reviewer_from_bug(self, bugs, bug_id): 157 patches = bugs.fetch_reviewed_patches_from_bug(bug_id) 158 if len(patches) != 1: 159 log("%s on bug %s, cannot infer reviewer." % (pluralize("reviewed patch", len(patches)), bug_id)) 160 return None 161 patch = patches[0] 162 reviewer = patch["reviewer"] 163 log("Guessing \"%s\" as reviewer from attachment %s on bug %s." % (reviewer, patch["id"], bug_id)) 164 return reviewer 165 166 def update_changelogs_with_reviewer(self, reviewer, bug_id, tool): 167 if not reviewer: 168 if not bug_id: 169 log("No bug id provided and --reviewer= not provided. Not updating ChangeLogs with reviewer.") 170 return 171 reviewer = self.guess_reviewer_from_bug(tool.bugs, bug_id) 172 173 if not reviewer: 174 log("Failed to guess reviewer from bug %s and --reviewer= not provided. Not updating ChangeLogs with reviewer." % bug_id) 175 return 176 177 for changelog_path in tool.scm().modified_changelogs(): 178 ChangeLog(changelog_path).set_reviewer(reviewer) 125 self._sequence = StepSequence([ 126 EnsureBuildersAreGreenStep, 127 UpdateChangelogsWithReviewerStep, 128 EnsureBuildersAreGreenStep, 129 BuildStep, 130 RunTestsStep, 131 CommitStep, 132 CloseBugForLandDiffStep, 133 ]) 134 Command.__init__(self, "Land the current working directory diff and updates the associated bug if any", "[BUGID]", options=self._sequence.options()) 179 135 180 136 def execute(self, options, args, tool): 181 137 bug_id = (args and args[0]) or parse_bug_id(tool.scm().create_patch()) 182 183 EnsureBuildersAreGreenStep(tool, options).run()184 185 os.chdir(tool.scm().checkout_root)186 self.update_changelogs_with_reviewer(options.reviewer, bug_id, tool)187 188 138 fake_patch = { 189 139 "id": None, 190 "bug_id": bug_id 140 "bug_id": bug_id, 191 141 } 192 193 sequence = LandDiffSequence(fake_patch, options, tool) 194 sequence.run() 142 state = {"patch": fake_patch} 143 self._sequence.run_and_handle_errors(tool, options, state) 195 144 196 145 … … 243 192 pass 244 193 194 # FIXME: Add a base class to share this code. 245 195 def _process_patch(self, patch, options, args, tool): 246 self._sequence.run_and_handle_errors(tool, options, patch) 196 state = {"patch": patch} 197 self._sequence.run_and_handle_errors(tool, options, state) 247 198 248 199 … … 265 216 pass 266 217 218 # FIXME: Add a base class to share this code. 267 219 def _process_patch(self, patch, options, args, tool): 268 self._sequence.run_and_handle_errors(tool, options, patch) 220 state = {"patch": patch} 221 self._sequence.run_and_handle_errors(tool, options, state) 269 222 270 223 271 224 class AbstractPatchLandingCommand(AbstractPatchProcessingCommand): 272 225 def __init__(self, help_text, args_description): 273 options = BuildSteps.cleaning_options() 274 options += BuildSteps.build_options() 275 options += BuildSteps.land_options() 276 AbstractPatchProcessingCommand.__init__(self, help_text, args_description, options) 226 self._sequence = StepSequence([ 227 CleanWorkingDirectoryStep, 228 UpdateStep, 229 ApplyPatchStep, 230 EnsureBuildersAreGreenStep, 231 BuildStep, 232 RunTestsStep, 233 CommitStep, 234 ClosePatchStep, 235 CloseBugStep, 236 ]) 237 AbstractPatchProcessingCommand.__init__(self, help_text, args_description, self._sequence.options()) 277 238 278 239 def _prepare_to_process(self, options, args, tool): 279 240 # Check the tree status first so we can fail early. 280 EnsureBuildersAreGreenStep(tool, options).run() 281 241 EnsureBuildersAreGreenStep(tool, options).run({}) 242 243 # FIXME: Add a base class to share this code. 282 244 def _process_patch(self, patch, options, args, tool): 283 s equence = LandingSequence(patch, options, tool)284 se quence.run_and_handle_errors()245 state = {"patch": patch} 246 self._sequence.run_and_handle_errors(tool, options, state) 285 247 286 248 … … 329 291 # Second, make new ChangeLog entries for this rollout. 330 292 # This could move to prepare-ChangeLog by adding a --revert= option. 331 PrepareChangelogStep(tool, None).run( )293 PrepareChangelogStep(tool, None).run({}) 332 294 for changelog_path in changelog_paths: 333 295 ChangeLog(changelog_path).update_for_revert(revision) … … 355 317 log("Failed to parse bug number from diff. No bugs will be updated/reopened after the rollout.") 356 318 357 CleanWorkingDirectoryStep(tool, options).run( )358 UpdateStep(tool, options).run( )319 CleanWorkingDirectoryStep(tool, options).run({}) 320 UpdateStep(tool, options).run({}) 359 321 tool.scm().apply_reverse_diff(revision) 360 322 self._create_changelogs_for_revert(tool, revision) -
trunk/WebKitTools/Scripts/modules/commands/queues.py
r51895 r52129 36 36 from modules.executive import ScriptError 37 37 from modules.grammar import pluralize 38 from modules.landingsequence import LandingSequence, LandingSequenceErrorHandler39 38 from modules.logging import error, log 40 39 from modules.multicommandtool import Command 41 40 from modules.patchcollection import PersistentPatchCollection, PersistentPatchCollectionDelegate 42 41 from modules.statusbot import StatusBot 42 from modules.stepsequence import StepSequenceErrorHandler 43 43 from modules.workqueue import WorkQueue, WorkQueueDelegate 44 44 … … 105 105 106 106 107 class CommitQueue(AbstractQueue, LandingSequenceErrorHandler):107 class CommitQueue(AbstractQueue, StepSequenceErrorHandler): 108 108 name = "commit-queue" 109 109 def __init__(self): … … 137 137 self.tool.bugs.reject_patch_from_commit_queue(patch["id"], message) 138 138 139 # LandingSequenceErrorHandler methods139 # StepSequenceErrorHandler methods 140 140 141 141 @classmethod 142 def handle_script_error(cls, tool, patch, script_error):143 tool.bugs.reject_patch_from_commit_queue( patch["id"], script_error.message_with_output())144 145 146 class AbstractReviewQueue(AbstractQueue, PersistentPatchCollectionDelegate, LandingSequenceErrorHandler):142 def handle_script_error(cls, tool, state, script_error): 143 tool.bugs.reject_patch_from_commit_queue(state["patch"]["id"], script_error.message_with_output()) 144 145 146 class AbstractReviewQueue(AbstractQueue, PersistentPatchCollectionDelegate, StepSequenceErrorHandler): 147 147 def __init__(self, options=None): 148 148 AbstractQueue.__init__(self, options) … … 180 180 log(message) 181 181 182 # LandingSequenceErrorHandler methods182 # StepSequenceErrorHandler methods 183 183 184 184 @classmethod 185 def handle_script_error(cls, tool, patch, script_error):185 def handle_script_error(cls, tool, state, script_error): 186 186 log(script_error.message_with_output()) 187 187 … … 206 206 207 207 @classmethod 208 def handle_script_error(cls, tool, patch, script_error):208 def handle_script_error(cls, tool, state, script_error): 209 209 command = script_error.script_args 210 210 if type(command) is list: … … 213 213 # have a better API. 214 214 if re.search("check-webkit-style", command): 215 message = "Attachment %s did not pass %s:\n\n%s" % ( patch["id"], cls.name, script_error.message_with_output(output_limit=5*1024))216 tool.bugs.post_comment_to_bug( patch["bug_id"], message, cc=cls.watchers)215 message = "Attachment %s did not pass %s:\n\n%s" % (state["patch"]["id"], cls.name, script_error.message_with_output(output_limit=5*1024)) 216 tool.bugs.post_comment_to_bug(state["patch"]["bug_id"], message, cc=cls.watchers) -
trunk/WebKitTools/Scripts/modules/stepsequence.py
r51956 r52129 34 34 35 35 36 class StepSequenceErrorHandler(): 37 @classmethod 38 def handle_script_error(cls, tool, patch, script_error): 39 raise NotImplementedError, "subclasses must implement" 40 41 36 42 class StepSequence(object): 37 43 def __init__(self, steps): … … 49 55 return collected_options 50 56 51 def _run(self, tool, options, patch):57 def _run(self, tool, options, state): 52 58 for step in self._steps: 53 step(tool, options , patch).run()59 step(tool, options).run(state) 54 60 55 def run_and_handle_errors(self, tool, options, patch=None): 61 def run_and_handle_errors(self, tool, options, state=None): 62 if not state: 63 state = {} 56 64 try: 57 self._run(tool, options, patch)65 self._run(tool, options, state) 58 66 except CheckoutNeedsUpdate, e: 59 67 log("Commit failed because the checkout is out of date. Please update and try again.") … … 65 73 if options.parent_command: 66 74 command = tool.command_by_name(options.parent_command) 67 command.handle_script_error(tool, patch, e)75 command.handle_script_error(tool, state, e) 68 76 WorkQueue.exit_after_handled_error(e)
Note: See TracChangeset
for help on using the changeset viewer.