Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Side by Side Diff: drover.py

Issue 12670008: Extend drover so it can revert any chrome revision. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 command = "%s %s" % (gcl_path, subcommand) 65 command = "%s %s" % (gcl_path, subcommand)
66 return os.system(command) 66 return os.system(command)
67 67
68 def gclUpload(revision, author): 68 def gclUpload(revision, author):
69 command = ("upload " + str(revision) + 69 command = ("upload " + str(revision) +
70 " --send_mail --no_presubmit --reviewers=" + author) 70 " --send_mail --no_presubmit --reviewers=" + author)
71 return runGcl(command) 71 return runGcl(command)
72 72
73 def getSVNInfo(url, revision): 73 def getSVNInfo(url, revision):
74 info = {} 74 info = {}
75 try: 75 svn_info = subprocess2.capture(
76 svn_info = subprocess2.check_output( 76 ['svn', 'info', '--non-interactive', '%s@%s' % (url, revision)],
77 ['svn', 'info', '%s@%s' % (url, revision)]).splitlines() 77 stderr=subprocess2.VOID).splitlines()
78 for line in svn_info: 78 for line in svn_info:
79 match = re.search(r"(.*?):(.*)", line) 79 match = re.search(r"(.*?):(.*)", line)
80 if match: 80 if match:
81 info[match.group(1).strip()] = match.group(2).strip() 81 info[match.group(1).strip()] = match.group(2).strip()
82 except subprocess2.CalledProcessError:
83 pass
84 return info 82 return info
85 83
86 def isSVNDirty(): 84 def isSVNDirty():
87 svn_status = subprocess2.check_output(['svn', 'status']).splitlines() 85 svn_status = subprocess2.check_output(['svn', 'status']).splitlines()
88 for line in svn_status: 86 for line in svn_status:
89 match = re.search(r"^[^X?]", line) 87 match = re.search(r"^[^X?]", line)
90 if match: 88 if match:
91 return True 89 return True
92 90
93 return False 91 return False
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 return default 482 return default
485 return answer 483 return answer
486 484
487 485
488 def drover(options, args): 486 def drover(options, args):
489 revision = options.revert or options.merge 487 revision = options.revert or options.merge
490 488
491 # Initialize some variables used below. They can be overwritten by 489 # Initialize some variables used below. They can be overwritten by
492 # the drover.properties file. 490 # the drover.properties file.
493 BASE_URL = "svn://svn.chromium.org/chrome" 491 BASE_URL = "svn://svn.chromium.org/chrome"
492 REVERT_ALT_URLS = ['svn://svn.chromium.org/chrome-internal',
493 'svn://svn.chromium.org/native_client']
494 TRUNK_URL = BASE_URL + "/trunk/src" 494 TRUNK_URL = BASE_URL + "/trunk/src"
495 BRANCH_URL = BASE_URL + "/branches/$branch/src" 495 BRANCH_URL = BASE_URL + "/branches/$branch/src"
496 SKIP_CHECK_WORKING = True 496 SKIP_CHECK_WORKING = True
497 PROMPT_FOR_AUTHOR = False 497 PROMPT_FOR_AUTHOR = False
498 498
499 # Translate a given milestone to the appropriate branch number. 499 # Translate a given milestone to the appropriate branch number.
500 if options.milestone: 500 if options.milestone:
501 options.branch = getBranchForMilestone(options.milestone) 501 options.branch = getBranchForMilestone(options.milestone)
502 if not options.branch: 502 if not options.branch:
503 return 1 503 return 1
(...skipping 10 matching lines...) Expand all
514 global file_pattern_ 514 global file_pattern_
515 if os.path.exists("drover.properties"): 515 if os.path.exists("drover.properties"):
516 FILE_PATTERN = file_pattern_ 516 FILE_PATTERN = file_pattern_
517 f = open("drover.properties") 517 f = open("drover.properties")
518 exec(f) 518 exec(f)
519 f.close() 519 f.close()
520 if FILE_PATTERN: 520 if FILE_PATTERN:
521 file_pattern_ = FILE_PATTERN 521 file_pattern_ = FILE_PATTERN
522 522
523 if options.revert and options.branch: 523 if options.revert and options.branch:
524 print 'Note: --branch is usually not needed for reverts.'
524 url = BRANCH_URL.replace("$branch", options.branch) 525 url = BRANCH_URL.replace("$branch", options.branch)
525 elif options.merge and options.sbranch: 526 elif options.merge and options.sbranch:
526 url = BRANCH_URL.replace("$branch", options.sbranch) 527 url = BRANCH_URL.replace("$branch", options.sbranch)
527 elif options.revert and options.url: 528 elif options.revert:
528 url = options.url 529 url = options.url or BASE_URL
529 file_pattern_ = r"[ ]+([MADUC])[ ]+((/.*)/(.*))" 530 file_pattern_ = r"[ ]+([MADUC])[ ]+((/.*)/(.*))"
530 else: 531 else:
531 url = TRUNK_URL 532 url = TRUNK_URL
532 533
533 working = options.workdir or DEFAULT_WORKING 534 working = options.workdir or DEFAULT_WORKING
534 535
535 if options.local: 536 if options.local:
536 working = os.getcwd() 537 working = os.getcwd()
537 if not inCheckoutRoot(working): 538 if not inCheckoutRoot(working):
538 print "'%s' appears not to be the root of a working copy" % working 539 print "'%s' appears not to be the root of a working copy" % working
539 return 1 540 return 1
540 if (isSVNDirty() and not 541 if (isSVNDirty() and not
541 prompt("Working copy contains uncommitted files. Continue?")): 542 prompt("Working copy contains uncommitted files. Continue?")):
542 return 1 543 return 1
543 544
545 if options.revert and not options.no_alt_urls:
546 for cur_url in [url] + REVERT_ALT_URLS:
547 try:
548 url_rev = int(getSVNInfo(cur_url, 'HEAD', ).get('Revision', ''))
549 if 0 <= url_rev - options.revert < 20000:
M-A Ruel 2013/03/18 17:09:37 Maybe 10000 to be on the safer side?
Isaac (away) 2013/03/18 19:25:59 I started w/ 10000 but it's only 2 months of chrom
550 if cur_url != url:
551 print 'Guessing svn repo: %s.' % cur_url,
552 print 'Use --no-alt-urls to disable heuristic.'
553 url = cur_url
554 break
555 except ValueError:
556 pass
544 command = 'svn log ' + url + " -r "+str(revision) + " -v" 557 command = 'svn log ' + url + " -r "+str(revision) + " -v"
545 os.system(command) 558 os.system(command)
546 559
547 if not (options.revertbot or prompt("Is this the correct revision?")): 560 if not (options.revertbot or prompt("Is this the correct revision?")):
548 return 0 561 return 0
549 562
550 if (os.path.exists(working)) and not options.local: 563 if (os.path.exists(working)) and not options.local:
551 if not (options.revertbot or SKIP_CHECK_WORKING or 564 if not (options.revertbot or SKIP_CHECK_WORKING or
552 prompt("Working directory: '%s' already exists, clobber?" % working)): 565 prompt("Working directory: '%s' already exists, clobber?" % working)):
553 return 0 566 return 0
(...skipping 11 matching lines...) Expand all
565 checkoutRevision(url, revision, branch_url) 578 checkoutRevision(url, revision, branch_url)
566 # Merge everything that changed 579 # Merge everything that changed
567 mergeRevision(url, revision) 580 mergeRevision(url, revision)
568 # "Export" files that were added from the source and add them to branch 581 # "Export" files that were added from the source and add them to branch
569 exportRevision(url, revision) 582 exportRevision(url, revision)
570 # Delete directories that were deleted (file deletes are handled in the 583 # Delete directories that were deleted (file deletes are handled in the
571 # merge). 584 # merge).
572 deleteRevision(url, revision) 585 deleteRevision(url, revision)
573 elif options.revert: 586 elif options.revert:
574 action = "Revert" 587 action = "Revert"
575 if options.branch:
576 url = BRANCH_URL.replace("$branch", options.branch)
577 pop_em = not options.url 588 pop_em = not options.url
578 checkoutRevision(url, revision, url, True, pop_em) 589 checkoutRevision(url, revision, url, True, pop_em)
579 revertRevision(url, revision) 590 revertRevision(url, revision)
580 revertExportRevision(url, revision) 591 revertExportRevision(url, revision)
581 592
582 # Check the base url so we actually find the author who made the change 593 # Check the base url so we actually find the author who made the change
583 if options.auditor: 594 if options.auditor:
584 author = options.auditor 595 author = options.auditor
585 else: 596 else:
586 author = getAuthor(url, revision) 597 author = getAuthor(url, revision)
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 option_parser.add_option('-s', '--sbranch', 676 option_parser.add_option('-s', '--sbranch',
666 help='Source branch for merge') 677 help='Source branch for merge')
667 option_parser.add_option('-r', '--revert', type="int", 678 option_parser.add_option('-r', '--revert', type="int",
668 help='Revision to revert') 679 help='Revision to revert')
669 option_parser.add_option('-w', '--workdir', 680 option_parser.add_option('-w', '--workdir',
670 help='subdir to use for the revert') 681 help='subdir to use for the revert')
671 option_parser.add_option('-u', '--url', 682 option_parser.add_option('-u', '--url',
672 help='svn url to use for the revert') 683 help='svn url to use for the revert')
673 option_parser.add_option('-a', '--auditor', 684 option_parser.add_option('-a', '--auditor',
674 help='overrides the author for reviewer') 685 help='overrides the author for reviewer')
675 option_parser.add_option('', '--revertbot', action='store_true', 686 option_parser.add_option('--revertbot', action='store_true',
676 default=False) 687 default=False)
677 option_parser.add_option('', '--revertbot-commit', action='store_true', 688 option_parser.add_option('--no-alt-urls', action='store_true',
689 help='Disable heuristics used to determine svn url')
690 option_parser.add_option('--revertbot-commit', action='store_true',
678 default=False) 691 default=False)
679 option_parser.add_option('', '--revertbot-reviewers') 692 option_parser.add_option('--revertbot-reviewers')
680 options, args = option_parser.parse_args() 693 options, args = option_parser.parse_args()
681 694
682 if not options.merge and not options.revert: 695 if not options.merge and not options.revert:
683 option_parser.error("You need at least --merge or --revert") 696 option_parser.error("You need at least --merge or --revert")
684 return 1 697 return 1
685 698
686 if options.merge and not (options.branch or options.milestone or 699 if options.merge and not (options.branch or options.milestone or
687 options.local): 700 options.local):
688 option_parser.error("--merge requires either --branch " 701 option_parser.error("--merge requires either --branch "
689 "or --milestone or --local") 702 "or --milestone or --local")
690 return 1 703 return 1
691 704
692 if options.local and (options.revert or options.branch or options.milestone): 705 if options.local and (options.revert or options.branch or options.milestone):
693 option_parser.error("--local cannot be used with --revert " 706 option_parser.error("--local cannot be used with --revert "
694 "or --branch or --milestone") 707 "or --branch or --milestone")
695 return 1 708 return 1
696 709
697 if options.branch and options.milestone: 710 if options.branch and options.milestone:
698 option_parser.error("--branch cannot be used with --milestone") 711 option_parser.error("--branch cannot be used with --milestone")
699 return 1 712 return 1
700 713
701 return drover(options, args) 714 return drover(options, args)
702 715
703 716
704 if __name__ == "__main__": 717 if __name__ == "__main__":
705 sys.exit(main()) 718 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698