Changeset 53729 in webkit
- Timestamp:
- Jan 22, 2010 3:58:03 PM (14 years ago)
- Location:
- trunk/WebKitTools
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKitTools/ChangeLog
r53728 r53729 1 2010-01-22 Adam Barth <abarth@webkit.org> 2 3 Reviewed by Eric Seidel. 4 5 Make bugzilla.py and webkitport.py conform to pep8 6 https://bugs.webkit.org/show_bug.cgi?id=34015 7 8 This patch makes webkitport.py and bugzilla.py mostly conform to PEP8 9 style as enforced by pep8.py. I wasn't able to get rid of all the 10 errors because I'm not sure how to wrap some lines properly. Also, 11 there are a few deprication errors that I couldn't resolve easily. 12 However, this is a massive improvement in compliance. 13 14 * Scripts/webkitpy/bugzilla.py: 15 * Scripts/webkitpy/webkitport.py: 16 1 17 2010-01-22 Adam Barth <abarth@webkit.org> 2 18 -
trunk/WebKitTools/Scripts/webkitpy/bugzilla.py
r53542 r53729 1 1 # Copyright (c) 2009, Google Inc. All rights reserved. 2 2 # Copyright (c) 2009 Apple Inc. All rights reserved. 3 # 3 # 4 4 # Redistribution and use in source and binary forms, with or without 5 5 # modification, are permitted provided that the following conditions are 6 6 # met: 7 # 7 # 8 8 # * Redistributions of source code must retain the above copyright 9 9 # notice, this list of conditions and the following disclaimer. … … 15 15 # contributors may be used to endorse or promote products derived from 16 16 # this software without specific prior written permission. 17 # 17 # 18 18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT … … 46 46 from mechanize import Browser 47 47 48 48 49 def parse_bug_id(message): 49 50 match = re.search("http\://webkit\.org/b/(?P<bug_id>\d+)", message) 50 51 if match: 51 52 return int(match.group('bug_id')) 52 match = re.search(Bugzilla.bug_server_regex + "show_bug\.cgi\?id=(?P<bug_id>\d+)", message) 53 match = re.search( 54 Bugzilla.bug_server_regex + "show_bug\.cgi\?id=(?P<bug_id>\d+)", 55 message) 53 56 if match: 54 57 return int(match.group('bug_id')) … … 61 64 62 65 class Attachment(object): 66 63 67 def __init__(self, attachment_dictionary, bug): 64 68 self._attachment_dictionary = attachment_dictionary … … 74 78 75 79 def attacher_is_committer(self): 76 return self._bugzilla.committers.committer_by_email(patch.attacher_email()) 80 return self._bugzilla.committers.committer_by_email( 81 patch.attacher_email()) 77 82 78 83 def attacher_email(self): … … 101 106 102 107 def url(self): 103 # FIXME: This should just return self._bugzilla().attachment_url_for_id(self.id()). scm_unittest.py depends on the current behavior. 108 # FIXME: This should just return 109 # self._bugzilla().attachment_url_for_id(self.id()). scm_unittest.py 110 # depends on the current behavior. 104 111 return self._attachment_dictionary.get("url") 105 112 … … 108 115 if not email: 109 116 return None 110 committer = getattr(self._bugzilla().committers, "%s_by_email" % flag)(email) 117 committer = getattr(self._bugzilla().committers, 118 "%s_by_email" % flag)(email) 111 119 if committer: 112 120 return committer 113 log("Warning, attachment %s on bug %s has invalid %s (%s)" % (self._attachment_dictionary['id'], self._attachment_dictionary['bug_id'], flag, email)) 121 log("Warning, attachment %s on bug %s has invalid %s (%s)" % ( 122 self._attachment_dictionary['id'], 123 self._attachment_dictionary['bug_id'], flag, email)) 114 124 115 125 def reviewer(self): … … 124 134 125 135 126 # FIXME: This class is kinda a hack for now. It exists so we have one place127 # to hold bug logic, even if much of the code deals with dictionaries still.128 136 class Bug(object): 137 # FIXME: This class is kinda a hack for now. It exists so we have one 138 # place to hold bug logic, even if much of the code deals with 139 # dictionaries still. 140 129 141 def __init__(self, bug_dictionary, bugzilla): 130 142 self.bug_dictionary = bug_dictionary … … 141 153 attachments = self.bug_dictionary["attachments"] 142 154 if not include_obsolete: 143 attachments = filter(lambda attachment: not attachment["is_obsolete"], attachments) 155 attachments = filter(lambda attachment: 156 not attachment["is_obsolete"], attachments) 144 157 return [Attachment(attachment, self) for attachment in attachments] 145 158 146 159 def patches(self, include_obsolete=False): 147 return [patch for patch in self.attachments(include_obsolete) if patch.is_patch()] 160 return [patch for patch in self.attachments(include_obsolete) 161 if patch.is_patch()] 148 162 149 163 def unreviewed_patches(self): … … 154 168 if include_invalid: 155 169 return patches 156 # Checking reviewer() ensures that it was both reviewed and has a valid reviewer. 170 # Checking reviewer() ensures that it was both reviewed and has a valid 171 # reviewer. 157 172 return filter(lambda patch: patch.reviewer(), patches) 158 173 159 174 def commit_queued_patches(self, include_invalid=False): 160 patches = [patch for patch in self.patches() if patch.commit_queue() == "+"] 175 patches = [patch for patch in self.patches() 176 if patch.commit_queue() == "+"] 161 177 if include_invalid: 162 178 return patches 163 # Checking committer() ensures that it was both commit-queue+'d and has a valid committer. 179 # Checking committer() ensures that it was both commit-queue+'d and has 180 # a valid committer. 164 181 return filter(lambda patch: patch.committer(), patches) 165 182 … … 167 184 # A container for all of the logic for making and parsing buzilla queries. 168 185 class BugzillaQueries(object): 186 169 187 def __init__(self, bugzilla): 170 188 self._bugzilla = bugzilla 171 189 172 # Note: _load_query and _fetch_bug are the only two methods which access self._bugzilla. 190 # Note: _load_query and _fetch_bug are the only two methods which access 191 # self._bugzilla. 192 173 193 def _load_query(self, query): 174 194 self._bugzilla.authenticate() … … 180 200 return self._bugzilla.fetch_bug(bug_id) 181 201 182 183 202 def _fetch_bug_ids_advanced_query(self, query): 184 203 soup = BeautifulSoup(self._load_query(query)) 185 # The contents of the <a> inside the cells in the first column happen to be the bug id. 186 return [int(bug_link_cell.find("a").string) for bug_link_cell in soup('td', "first-child")] 204 # The contents of the <a> inside the cells in the first column happen 205 # to be the bug id. 206 return [int(bug_link_cell.find("a").string) 207 for bug_link_cell in soup('td', "first-child")] 187 208 188 209 def _parse_attachment_ids_request_query(self, page): … … 190 211 attachment_href = re.compile("attachment.cgi\?id=\d+&action=review") 191 212 attachment_links = SoupStrainer("a", href=attachment_href) 192 return [int(digits.search(tag["href"]).group(0)) for tag in BeautifulSoup(page, parseOnlyThese=attachment_links)] 213 return [int(digits.search(tag["href"]).group(0)) 214 for tag in BeautifulSoup(page, parseOnlyThese=attachment_links)] 193 215 194 216 def _fetch_attachment_ids_request_query(self, query): … … 201 223 202 224 def fetch_patches_from_pending_commit_list(self): 203 return sum([self._fetch_bug(bug_id).reviewed_patches() for bug_id in self.fetch_bug_ids_from_pending_commit_list()], []) 225 return sum([self._fetch_bug(bug_id).reviewed_patches() 226 for bug_id in self.fetch_bug_ids_from_pending_commit_list()], []) 204 227 205 228 def fetch_bug_ids_from_commit_queue(self): … … 207 230 return self._fetch_bug_ids_advanced_query(commit_queue_url) 208 231 209 # This function will only return patches which have valid committers set. It won't reject patches with invalid committers/reviewers.210 232 def fetch_patches_from_commit_queue(self): 211 return sum([self._fetch_bug(bug_id).commit_queued_patches() for bug_id in self.fetch_bug_ids_from_commit_queue()], []) 233 # This function will only return patches which have valid committers 234 # set. It won't reject patches with invalid committers/reviewers. 235 return sum([self._fetch_bug(bug_id).commit_queued_patches() 236 for bug_id in self.fetch_bug_ids_from_commit_queue()], []) 212 237 213 238 def _fetch_bug_ids_from_review_queue(self): … … 216 241 217 242 def fetch_patches_from_review_queue(self, limit=None): 218 return sum([self._fetch_bug(bug_id).unreviewed_patches() for bug_id in self._fetch_bug_ids_from_review_queue()[:limit]], []) # [:None] returns the whole array. 219 220 # FIXME: Why do we have both fetch_patches_from_review_queue and fetch_attachment_ids_from_review_queue?? 243 # [:None] returns the whole array. 244 return sum([self._fetch_bug(bug_id).unreviewed_patches() 245 for bug_id in self._fetch_bug_ids_from_review_queue()[:limit]], []) 246 247 # FIXME: Why do we have both fetch_patches_from_review_queue and 248 # fetch_attachment_ids_from_review_queue?? 221 249 # NOTE: This is also the only client of _fetch_attachment_ids_request_query 250 222 251 def fetch_attachment_ids_from_review_queue(self): 223 252 review_queue_url = "request.cgi?action=queue&type=review&group=type" … … 226 255 227 256 class CommitterValidator(object): 257 228 258 def __init__(self, bugzilla): 229 259 self._bugzilla = bugzilla 230 260 231 # _view_source_ linkbelongs in some sort of webkit_config.py module.232 def _view_source_ link(self, local_path):261 # _view_source_url belongs in some sort of webkit_config.py module. 262 def _view_source_url(self, local_path): 233 263 return "http://trac.webkit.org/browser/trunk/%s" % local_path 234 264 235 265 def _flag_permission_rejection_message(self, setter_email, flag_name): 236 committer_list = "WebKitTools/Scripts/webkitpy/committers.py" # This could be computed from CommitterList.__file__ 237 contribution_guidlines_url = "http://webkit.org/coding/contributing.html" # Should come from some webkit_config.py 238 queue_administrator = "eseidel@chromium.org" # This could be queried from the status_server. 239 queue_name = "commit-queue" # This could be queried from the tool. 240 rejection_message = "%s does not have %s permissions according to %s." % (setter_email, flag_name, self._view_source_link(committer_list)) 241 rejection_message += "\n\n- If you do not have %s rights please read %s for instructions on how to use bugzilla flags." % (flag_name, contribution_guidlines_url) 242 rejection_message += "\n\n- If you have %s rights please correct the error in %s by adding yourself to the file (no review needed)." % (flag_name, committer_list) 243 rejection_message += " Due to bug 30084 the %s will require a restart after your change." % queue_name 244 rejection_message += " Please contact %s to request a %s restart." % (queue_administrator, queue_name) 245 rejection_message += " After restart the %s will correctly respect your %s rights." % (queue_name, flag_name) 246 return rejection_message 266 # This could be computed from CommitterList.__file__ 267 committer_list = "WebKitTools/Scripts/webkitpy/committers.py" 268 # Should come from some webkit_config.py 269 contribution_guidlines = "http://webkit.org/coding/contributing.html" 270 # This could be queried from the status_server. 271 queue_administrator = "eseidel@chromium.org" 272 # This could be queried from the tool. 273 queue_name = "commit-queue" 274 message = "%s does not have %s permissions according to %s." % ( 275 setter_email, 276 flag_name, 277 self._view_source_url(committer_list)) 278 message += "\n\n- If you do not have %s rights please read %s for instructions on how to use bugzilla flags." % ( 279 flag_name, contribution_guidlines) 280 message += "\n\n- If you have %s rights please correct the error in %s by adding yourself to the file (no review needed). " % ( 281 flag_name, committer_list) 282 message += "Due to bug 30084 the %s will require a restart after your change. " % queue_name 283 message += "Please contact %s to request a %s restart. " % ( 284 queue_administrator, queue_name) 285 message += "After restart the %s will correctly respect your %s rights." % ( 286 queue_name, flag_name) 287 return message 247 288 248 289 def _validate_setter_email(self, patch, result_key, rejection_function): 249 290 committer = getattr(patch, result_key)() 250 # If the flag is set, and we don't recognize the setter, reject the flag! 291 # If the flag is set, and we don't recognize the setter, reject the 292 # flag! 251 293 setter_email = patch._attachment_dictionary.get("%s_email" % result_key) 252 294 if setter_email and not committer: 253 rejection_function(patch.id(), self._flag_permission_rejection_message(setter_email, result_key)) 295 rejection_function(patch.id(), 296 self._flag_permission_rejection_message(setter_email, 297 result_key)) 254 298 return False 255 299 return True … … 258 302 validated_patches = [] 259 303 for patch in patches: 260 if self._validate_setter_email(patch, "reviewer", self.reject_patch_from_review_queue) and self._validate_setter_email(patch, "committer", self.reject_patch_from_commit_queue): 304 if (self._validate_setter_email( 305 patch, "reviewer", self.reject_patch_from_review_queue) 306 and self._validate_setter_email( 307 patch, "committer", self.reject_patch_from_commit_queue)): 261 308 validated_patches.append(patch) 262 309 return validated_patches 263 310 264 def reject_patch_from_commit_queue(self, attachment_id, additional_comment_text=None): 311 def reject_patch_from_commit_queue(self, 312 attachment_id, 313 additional_comment_text=None): 265 314 comment_text = "Rejecting patch %s from commit-queue." % attachment_id 266 self._bugzilla.set_flag_on_attachment(attachment_id, 'commit-queue', '-', comment_text, additional_comment_text) 267 268 def reject_patch_from_review_queue(self, attachment_id, additional_comment_text=None): 315 self._bugzilla.set_flag_on_attachment(attachment_id, 316 "commit-queue", 317 "-", 318 comment_text, 319 additional_comment_text) 320 321 def reject_patch_from_review_queue(self, 322 attachment_id, 323 additional_comment_text=None): 269 324 comment_text = "Rejecting patch %s from review queue." % attachment_id 270 self._bugzilla.set_flag_on_attachment(attachment_id, 'review', '-', comment_text, additional_comment_text) 325 self._bugzilla.set_flag_on_attachment(attachment_id, 326 'review', 327 '-', 328 comment_text, 329 additional_comment_text) 271 330 272 331 273 332 class Bugzilla(object): 333 274 334 def __init__(self, dryrun=False, committers=CommitterList()): 275 335 self.dryrun = dryrun … … 278 338 self.committers = committers 279 339 280 # FIXME: We should use some sort of Browser mock object when in dryrun mode (to prevent any mistakes). 340 # FIXME: We should use some sort of Browser mock object when in dryrun 341 # mode (to prevent any mistakes). 281 342 self.browser = Browser() 282 # Ignore bugs.webkit.org/robots.txt until we fix it to allow this script 343 # Ignore bugs.webkit.org/robots.txt until we fix it to allow this 344 # script. 283 345 self.browser.set_handle_robots(False) 284 346 … … 291 353 def bug_url_for_bug_id(self, bug_id, xml=False): 292 354 content_type = "&ctype=xml" if xml else "" 293 return "%sshow_bug.cgi?id=%s%s" % (self.bug_server_url, bug_id, content_type) 355 return "%sshow_bug.cgi?id=%s%s" % (self.bug_server_url, 356 bug_id, 357 content_type) 294 358 295 359 def short_bug_url_for_bug_id(self, bug_id): … … 300 364 if action and action != "view": 301 365 action_param = "&action=%s" % action 302 return "%sattachment.cgi?id=%s%s" % (self.bug_server_url, attachment_id, action_param) 303 304 def _parse_attachment_flag(self, element, flag_name, attachment, result_key): 305 flag = element.find('flag', attrs={'name' : flag_name}) 366 return "%sattachment.cgi?id=%s%s" % (self.bug_server_url, 367 attachment_id, 368 action_param) 369 370 def _parse_attachment_flag(self, 371 element, 372 flag_name, 373 attachment, 374 result_key): 375 flag = element.find('flag', attrs={'name': flag_name}) 306 376 if flag: 307 377 attachment[flag_name] = flag['status'] … … 320 390 attachment['attacher_email'] = str(element.find('attacher').string) 321 391 attachment['type'] = str(element.find('type').string) 322 self._parse_attachment_flag(element, 'review', attachment, 'reviewer_email') 323 self._parse_attachment_flag(element, 'commit-queue', attachment, 'committer_email') 392 self._parse_attachment_flag( 393 element, 'review', attachment, 'reviewer_email') 394 self._parse_attachment_flag( 395 element, 'commit-queue', attachment, 'committer_email') 324 396 return attachment 325 397 … … 331 403 bug["reporter_email"] = str(soup.find("reporter").string) 332 404 bug["assigned_to_email"] = str(soup.find("assigned_to").string) 333 bug["cc_emails"] = [str(element.string) for element in soup.findAll('cc')] 405 bug["cc_emails"] = [str(element.string) 406 for element in soup.findAll('cc')] 334 407 bug["attachments"] = [self._parse_attachment_element(element, bug["id"]) for element in soup.findAll('attachment')] 335 408 return bug 336 409 337 # Makes testing fetch_*_from_bug() possible until we have a better BugzillaNetwork abstration. 410 # Makes testing fetch_*_from_bug() possible until we have a better 411 # BugzillaNetwork abstration. 412 338 413 def _fetch_bug_page(self, bug_id): 339 414 bug_url = self.bug_url_for_bug_id(bug_id, xml=True) … … 345 420 346 421 # FIXME: A BugzillaCache object should provide all these fetch_ methods. 422 347 423 def fetch_bug(self, bug_id): 348 424 return Bug(self.fetch_bug_dictionary(bug_id), self) 349 425 350 426 def _parse_bug_id_from_attachment_page(self, page): 351 up_link = BeautifulSoup(page).find('link', rel='Up') # The "Up" relation happens to point to the bug. 427 # The "Up" relation happens to point to the bug. 428 up_link = BeautifulSoup(page).find('link', rel='Up') 352 429 if not up_link: 353 return None # This attachment does not exist (or you don't have permissions to view it). 430 # This attachment does not exist (or you don't have permissions to 431 # view it). 432 return None 354 433 match = re.search("show_bug.cgi\?id=(?P<bug_id>\d+)", up_link['href']) 355 434 return int(match.group('bug_id')) … … 363 442 return self._parse_bug_id_from_attachment_page(page) 364 443 365 # FIXME: This should just return Attachment(id), which should be able to lazily fetch needed data. 444 # FIXME: This should just return Attachment(id), which should be able to 445 # lazily fetch needed data. 446 366 447 def fetch_attachment(self, attachment_id): 367 # We could grab all the attachment details off of the attachment edit page 368 # but we already have working code to do so off of the bugs page, so re-use that. 448 # We could grab all the attachment details off of the attachment edit 449 # page but we already have working code to do so off of the bugs page, 450 # so re-use that. 369 451 bug_id = self.bug_id_for_attachment_id(attachment_id) 370 452 if not bug_id: 371 453 return None 372 for attachment in self.fetch_bug(bug_id).attachments(include_obsolete=True): 454 attachments = self.fetch_bug(bug_id).attachments(include_obsolete=True) 455 for attachment in attachments: 373 456 if attachment.id() == int(attachment_id): 374 457 return attachment … … 384 467 return 385 468 386 (username, password) = Credentials(self.bug_server_host, git_prefix="bugzilla").read_credentials() 469 (username, password) = Credentials( 470 self.bug_server_host, git_prefix="bugzilla").read_credentials() 387 471 388 472 log("Logging in as %s..." % username) … … 394 478 395 479 match = re.search("<title>(.+?)</title>", response.read()) 396 # If the resulting page has a title, and it contains the word "invalid" assume it's the login failure page. 480 # If the resulting page has a title, and it contains the word "invalid" 481 # assume it's the login failure page. 397 482 if match and re.search("Invalid", match.group(1), re.IGNORECASE): 398 483 # FIXME: We could add the ability to try again on failure. … … 401 486 self.authenticated = True 402 487 403 def _fill_attachment_form(self, description, patch_file_object, comment_text=None, mark_for_review=False, mark_for_commit_queue=False, mark_for_landing=False, bug_id=None): 488 def _fill_attachment_form(self, 489 description, 490 patch_file_object, 491 comment_text=None, 492 mark_for_review=False, 493 mark_for_commit_queue=False, 494 mark_for_landing=False, bug_id=None): 404 495 self.browser['description'] = description 405 496 self.browser['ispatch'] = ("1",) … … 417 508 else: 418 509 patch_name ="%s.patch" % timestamp() 419 self.browser.add_file(patch_file_object, "text/plain", patch_name, 'data') 420 421 def add_patch_to_bug(self, bug_id, patch_file_object, description, comment_text=None, mark_for_review=False, mark_for_commit_queue=False, mark_for_landing=False): 422 self.authenticate() 423 424 log('Adding patch "%s" to %sshow_bug.cgi?id=%s' % (description, self.bug_server_url, bug_id)) 425 426 if self.dryrun: 427 log(comment_text) 428 return 429 430 self.browser.open("%sattachment.cgi?action=enter&bugid=%s" % (self.bug_server_url, bug_id)) 510 self.browser.add_file(patch_file_object, 511 "text/plain", 512 patch_name, 513 'data') 514 515 def add_patch_to_bug(self, 516 bug_id, 517 patch_file_object, 518 description, 519 comment_text=None, 520 mark_for_review=False, 521 mark_for_commit_queue=False, 522 mark_for_landing=False): 523 self.authenticate() 524 525 log('Adding patch "%s" to %sshow_bug.cgi?id=%s' % (description, 526 self.bug_server_url, 527 bug_id)) 528 529 if self.dryrun: 530 log(comment_text) 531 return 532 533 self.browser.open("%sattachment.cgi?action=enter&bugid=%s" % ( 534 self.bug_server_url, bug_id)) 431 535 self.browser.select_form(name="entryform") 432 self._fill_attachment_form(description, patch_file_object, mark_for_review=mark_for_review, mark_for_commit_queue=mark_for_commit_queue, mark_for_landing=mark_for_landing, bug_id=bug_id) 536 self._fill_attachment_form(description, 537 patch_file_object, 538 mark_for_review=mark_for_review, 539 mark_for_commit_queue=mark_for_commit_queue, 540 mark_for_landing=mark_for_landing, 541 bug_id=bug_id) 433 542 if comment_text: 434 543 log(comment_text) … … 446 555 447 556 def _check_create_bug_response(self, response_html): 448 match = re.search("<title>Bug (?P<bug_id>\d+) Submitted</title>", response_html) 557 match = re.search("<title>Bug (?P<bug_id>\d+) Submitted</title>", 558 response_html) 449 559 if match: 450 560 return match.group('bug_id') 451 561 452 match = re.search('<div id="bugzilla-body">(?P<error_message>.+)<div id="footer">', response_html, re.DOTALL) 562 match = re.search( 563 '<div id="bugzilla-body">(?P<error_message>.+)<div id="footer">', 564 response_html, 565 re.DOTALL) 453 566 error_message = "FAIL" 454 567 if match: 455 text_lines = BeautifulSoup(match.group('error_message')).findAll(text=True) 456 error_message = "\n" + '\n'.join([" " + line.strip() for line in text_lines if line.strip()]) 568 text_lines = BeautifulSoup( 569 match.group('error_message')).findAll(text=True) 570 error_message = "\n" + '\n'.join( 571 [" " + line.strip() 572 for line in text_lines if line.strip()]) 457 573 raise Exception("Bug not created: %s" % error_message) 458 574 459 def create_bug(self, bug_title, bug_description, component=None, patch_file_object=None, patch_description=None, cc=None, mark_for_review=False, mark_for_commit_queue=False): 575 def create_bug(self, 576 bug_title, 577 bug_description, 578 component=None, 579 patch_file_object=None, 580 patch_description=None, 581 cc=None, 582 mark_for_review=False, 583 mark_for_commit_queue=False): 460 584 self.authenticate() 461 585 … … 480 604 481 605 if patch_file_object: 482 self._fill_attachment_form(patch_description, patch_file_object, mark_for_review=mark_for_review, mark_for_commit_queue=mark_for_commit_queue) 606 self._fill_attachment_form( 607 patch_description, 608 patch_file_object, 609 mark_for_review=mark_for_review, 610 mark_for_commit_queue=mark_for_commit_queue) 483 611 484 612 response = self.browser.submit() … … 497 625 raise Exception("Don't know how to find flag named \"%s\"" % flag_name) 498 626 499 def clear_attachment_flags(self, attachment_id, additional_comment_text=None): 627 def clear_attachment_flags(self, 628 attachment_id, 629 additional_comment_text=None): 500 630 self.authenticate() 501 631 … … 515 645 self.browser.submit() 516 646 517 # FIXME: We need a way to test this on a live bugzilla instance. 518 def set_flag_on_attachment(self, attachment_id, flag_name, flag_value, comment_text, additional_comment_text): 647 def set_flag_on_attachment(self, 648 attachment_id, 649 flag_name, 650 flag_value, 651 comment_text, 652 additional_comment_text): 653 # FIXME: We need a way to test this function on a live bugzilla 654 # instance. 655 519 656 self.authenticate() 520 657 … … 532 669 self.browser.submit() 533 670 534 # FIXME: All of these bug editing methods have a ridiculous amount of copy/paste code. 535 def obsolete_attachment(self, attachment_id, comment_text = None): 671 # FIXME: All of these bug editing methods have a ridiculous amount of 672 # copy/paste code. 673 674 def obsolete_attachment(self, attachment_id, comment_text=None): 536 675 self.authenticate() 537 676 … … 549 688 if comment_text: 550 689 log(comment_text) 551 # Bugzilla has two textareas named 'comment', one is somehow hidden. We want the first. 690 # Bugzilla has two textareas named 'comment', one is somehow 691 # hidden. We want the first. 552 692 self.browser.set_value(comment_text, name='comment', nr=0) 553 693 self.browser.submit() … … 556 696 self.authenticate() 557 697 558 log("Adding %s to the CC list for bug %s" % (email_address_list, bug_id)) 698 log("Adding %s to the CC list for bug %s" % (email_address_list, 699 bug_id)) 559 700 if self.dryrun: 560 701 return … … 617 758 618 759 log("Re-opening bug %s" % bug_id) 619 log(comment_text) # Bugzilla requires a comment when re-opening a bug, so we know it will never be None. 760 # Bugzilla requires a comment when re-opening a bug, so we know it will 761 # never be None. 762 log(comment_text) 620 763 if self.dryrun: 621 764 return … … 624 767 self.browser.select_form(name="changeform") 625 768 bug_status = self.browser.find_control("bug_status", type="select") 626 # This is a hack around the fact that ClientForm.ListControl seems to have no simpler way to ask 627 # if a control has an item named "REOPENED" without using exceptions for control flow. 769 # This is a hack around the fact that ClientForm.ListControl seems to 770 # have no simpler way to ask if a control has an item named "REOPENED" 771 # without using exceptions for control flow. 628 772 possible_bug_statuses = map(lambda item: item.name, bug_status.items) 629 773 if "REOPENED" in possible_bug_statuses: 630 774 bug_status.value = ["REOPENED"] 631 775 else: 632 log("Did not reopen bug %s. It appears to already be open with status %s." % (bug_id, bug_status.value)) 776 log("Did not reopen bug %s. " + 777 "It appears to already be open with status %s." % ( 778 bug_id, bug_status.value)) 633 779 self.browser['comment'] = comment_text 634 780 self.browser.submit() -
trunk/WebKitTools/Scripts/webkitpy/webkitport.py
r53011 r53729 1 1 # Copyright (C) 2009, Google Inc. All rights reserved. 2 # 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 # 6 # 7 7 # * Redistributions of source code must retain the above copyright 8 8 # notice, this list of conditions and the following disclaimer. … … 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 … … 36 36 37 37 class WebKitPort(object): 38 38 39 # We might need to pass scm into this function for scm.checkout_root 39 40 @classmethod … … 54 55 @classmethod 55 56 def name(cls): 56 raise NotImplementedError , "subclasses must implement"57 raise NotImplementedError("subclasses must implement") 57 58 58 59 @classmethod 59 60 def flag(cls): 60 raise NotImplementedError , "subclasses must implement"61 raise NotImplementedError("subclasses must implement") 61 62 62 63 @classmethod … … 91 92 92 93 class MacPort(WebKitPort): 94 93 95 @classmethod 94 96 def name(cls): … … 101 103 102 104 class GtkPort(WebKitPort): 105 103 106 @classmethod 104 107 def name(cls): … … 124 127 125 128 class QtPort(WebKitPort): 129 126 130 @classmethod 127 131 def name(cls): … … 141 145 142 146 class ChromiumPort(WebKitPort): 147 143 148 @classmethod 144 149 def name(cls):
Note: See TracChangeset
for help on using the changeset viewer.