| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 import optparse | 6 import optparse |
| 7 import os | 7 import os |
| 8 import re | 8 import re |
| 9 import string | 9 import string |
| 10 import sys | 10 import sys |
| 11 import urllib2 | 11 import urllib2 |
| 12 import urlparse |
| 12 | 13 |
| 13 import breakpad # pylint: disable=W0611 | 14 import breakpad # pylint: disable=W0611 |
| 14 | 15 |
| 15 import gclient_utils | 16 import gclient_utils |
| 16 import subprocess2 | 17 import subprocess2 |
| 17 | 18 |
| 18 USAGE = """ | 19 USAGE = """ |
| 19 WARNING: Please use this tool in an empty directory | 20 WARNING: Please use this tool in an empty directory |
| 20 (or at least one that you don't mind clobbering.) | 21 (or at least one that you don't mind clobbering.) |
| 21 | 22 |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 # Not all of the platforms have the same branch. Prompt the user and return | 415 # Not all of the platforms have the same branch. Prompt the user and return |
| 415 # the greatest (by value) branch on success. | 416 # the greatest (by value) branch on success. |
| 416 if prompt("Not all platforms have the same branch number, " | 417 if prompt("Not all platforms have the same branch number, " |
| 417 "continue with branch %s?" % branch): | 418 "continue with branch %s?" % branch): |
| 418 return branch | 419 return branch |
| 419 | 420 |
| 420 # User cancelled. | 421 # User cancelled. |
| 421 return None | 422 return None |
| 422 | 423 |
| 423 | 424 |
| 425 def getSVNAuthInfo(folder=None): |
| 426 """Fetches SVN authorization information in the subversion auth folder and |
| 427 returns it as a dictionary of dictionaries.""" |
| 428 if not folder: |
| 429 if sys.platform == 'win32': |
| 430 folder = '%%APPDATA%\\Subversion\\auth' |
| 431 else: |
| 432 folder = '~/.subversion/auth' |
| 433 folder = os.path.expandvars(os.path.expanduser(folder)) |
| 434 svn_simple_folder = os.path.join(folder, 'svn.simple') |
| 435 results = {} |
| 436 try: |
| 437 for auth_file in os.listdir(svn_simple_folder): |
| 438 # Read the SVN auth file, convert it into a dictionary, and store it. |
| 439 results[auth_file] = dict(re.findall(r'K [0-9]+\n(.*)\nV [0-9]+\n(.*)\n', |
| 440 open(os.path.join(svn_simple_folder, auth_file)).read())) |
| 441 except Exception as _: |
| 442 pass |
| 443 return results |
| 444 |
| 445 |
| 446 def getCurrentSVNUsers(url): |
| 447 """Tries to fetch the current SVN in the current checkout by scanning the |
| 448 SVN authorization folder for a match with the current SVN URL.""" |
| 449 netloc = urlparse.urlparse(url)[1] |
| 450 auth_infos = getSVNAuthInfo() |
| 451 results = [] |
| 452 for _, auth_info in auth_infos.iteritems(): |
| 453 if ('svn:realmstring' in auth_info |
| 454 and netloc in auth_info['svn:realmstring']): |
| 455 username = auth_info['username'] |
| 456 results.append(username) |
| 457 if 'google.com' in username: |
| 458 results.append(username.replace('google.com', 'chromium.org')) |
| 459 return results |
| 460 |
| 461 |
| 424 def prompt(question): | 462 def prompt(question): |
| 425 while True: | 463 while True: |
| 426 print question + " [y|n]:", | 464 print question + " [y|n]:", |
| 427 answer = sys.stdin.readline() | 465 answer = sys.stdin.readline() |
| 428 if answer.lower().startswith('n'): | 466 if answer.lower().startswith('n'): |
| 429 return False | 467 return False |
| 430 elif answer.lower().startswith('y'): | 468 elif answer.lower().startswith('y'): |
| 431 return True | 469 return True |
| 432 | 470 |
| 433 | 471 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 revertExportRevision(url, revision) | 568 revertExportRevision(url, revision) |
| 531 | 569 |
| 532 # Check the base url so we actually find the author who made the change | 570 # Check the base url so we actually find the author who made the change |
| 533 if options.auditor: | 571 if options.auditor: |
| 534 author = options.auditor | 572 author = options.auditor |
| 535 else: | 573 else: |
| 536 author = getAuthor(url, revision) | 574 author = getAuthor(url, revision) |
| 537 if not author: | 575 if not author: |
| 538 author = getAuthor(TRUNK_URL, revision) | 576 author = getAuthor(TRUNK_URL, revision) |
| 539 | 577 |
| 578 # Check that the author of the CL is different than the user making |
| 579 # the revert. If they're the same, then we'll want to prompt the user |
| 580 # for a different reviewer to TBR. |
| 581 current_users = getCurrentSVNUsers(BASE_URL) |
| 582 is_self_revert = options.revert and author in current_users |
| 583 |
| 540 filename = str(revision)+".txt" | 584 filename = str(revision)+".txt" |
| 541 out = open(filename,"w") | 585 out = open(filename,"w") |
| 542 out.write(action +" " + str(revision) + " - ") | 586 out.write(action +" " + str(revision) + "\n") |
| 543 out.write(getRevisionLog(url, revision)) | 587 for line in getRevisionLog(url, revision).splitlines(): |
| 588 out.write('> %s\n' % line) |
| 544 if (author): | 589 if (author): |
| 545 out.write("\nTBR=" + author) | 590 out.write("\nTBR=" + author) |
| 546 out.close() | 591 out.close() |
| 547 | 592 |
| 548 change_cmd = 'change ' + str(revision) + " " + filename | 593 change_cmd = 'change ' + str(revision) + " " + filename |
| 549 if options.revertbot: | 594 if options.revertbot: |
| 550 if sys.platform == 'win32': | 595 if sys.platform == 'win32': |
| 551 os.environ['SVN_EDITOR'] = 'cmd.exe /c exit' | 596 os.environ['SVN_EDITOR'] = 'cmd.exe /c exit' |
| 552 else: | 597 else: |
| 553 os.environ['SVN_EDITOR'] = 'true' | 598 os.environ['SVN_EDITOR'] = 'true' |
| 554 runGcl(change_cmd) | 599 runGcl(change_cmd) |
| 555 os.unlink(filename) | 600 os.unlink(filename) |
| 556 | 601 |
| 557 if options.local: | 602 if options.local: |
| 558 return 0 | 603 return 0 |
| 559 | 604 |
| 560 print author | 605 print author |
| 561 print revision | 606 print revision |
| 562 print ("gcl upload " + str(revision) + | 607 print ("gcl upload " + str(revision) + |
| 563 " --send_mail --no_presubmit --reviewers=" + author) | 608 " --send_mail --no_presubmit --reviewers=" + author) |
| 564 | 609 |
| 565 if options.revertbot or prompt("Would you like to upload?"): | 610 if options.revertbot or prompt("Would you like to upload?"): |
| 566 if PROMPT_FOR_AUTHOR: | 611 if PROMPT_FOR_AUTHOR or is_self_revert: |
| 567 author = text_prompt("Enter new author or press enter to accept default", | 612 author = text_prompt("Enter new author or press enter to accept default", |
| 568 author) | 613 author) |
| 569 if options.revertbot and options.revertbot_reviewers: | 614 if options.revertbot and options.revertbot_reviewers: |
| 570 author += "," | 615 author += "," |
| 571 author += options.revertbot_reviewers | 616 author += options.revertbot_reviewers |
| 572 gclUpload(revision, author) | 617 gclUpload(revision, author) |
| 573 else: | 618 else: |
| 574 print "Deleting the changelist." | 619 print "Deleting the changelist." |
| 575 print "gcl delete " + str(revision) | 620 print "gcl delete " + str(revision) |
| 576 runGcl("delete " + str(revision)) | 621 runGcl("delete " + str(revision)) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 | 673 |
| 629 if options.branch and options.milestone: | 674 if options.branch and options.milestone: |
| 630 option_parser.error("--branch cannot be used with --milestone") | 675 option_parser.error("--branch cannot be used with --milestone") |
| 631 return 1 | 676 return 1 |
| 632 | 677 |
| 633 return drover(options, args) | 678 return drover(options, args) |
| 634 | 679 |
| 635 | 680 |
| 636 if __name__ == "__main__": | 681 if __name__ == "__main__": |
| 637 sys.exit(main()) | 682 sys.exit(main()) |
| OLD | NEW |