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

Side by Side Diff: drover.py

Issue 8498038: Drover: Add --milestone option to merge to a specific milestone. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: '' Created 9 years, 1 month 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) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 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 sys 10 import sys
11 import urllib2
10 12
11 import breakpad # pylint: disable=W0611 13 import breakpad # pylint: disable=W0611
12 14
13 import gclient_utils 15 import gclient_utils
14 import subprocess2 16 import subprocess2
15 17
16 USAGE = """ 18 USAGE = """
17 WARNING: Please use this tool in an empty directory 19 WARNING: Please use this tool in an empty directory
18 (or at least one that you don't mind clobbering.) 20 (or at least one that you don't mind clobbering.)
19 21
20 REQUIRES: SVN 1.5+ 22 REQUIRES: SVN 1.5+
21 NOTE: NO NEED TO CHECKOUT ANYTHING IN ADVANCE OF USING THIS TOOL. 23 NOTE: NO NEED TO CHECKOUT ANYTHING IN ADVANCE OF USING THIS TOOL.
22 Valid parameters: 24 Valid parameters:
23 25
24 [Merge from trunk to branch] 26 [Merge from trunk to branch]
25 --merge <revision> --branch <branch_num> 27 --merge <revision> --branch <branch_num>
26 Example: %(app)s --merge 12345 --branch 187 28 Example: %(app)s --merge 12345 --branch 187
27 29
30 [Merge from trunk to milestone]
31 --merge <revision> --milestone <milestone_num>
32 Example: %(app)s -- merge 12345 --milestone 16
33
28 [Merge from trunk to local copy] 34 [Merge from trunk to local copy]
29 --merge <revision> --local 35 --merge <revision> --local
30 Example: %(app)s --merge 12345 --local 36 Example: %(app)s --merge 12345 --local
31 37
32 [Merge from branch to branch] 38 [Merge from branch to branch]
33 --merge <revision> --sbranch <branch_num> --branch <branch_num> 39 --merge <revision> --sbranch <branch_num> --branch <branch_num>
34 Example: %(app)s --merge 12345 --sbranch 248 --branch 249 40 Example: %(app)s --merge 12345 --sbranch 248 --branch 249
35 41
36 [Revert from trunk] 42 [Revert from trunk]
37 --revert <revision> 43 --revert <revision>
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 return ['%s/%s' % (f[2], f[3]) for f in files_info if f[0] != 'A'] 355 return ['%s/%s' % (f[2], f[3]) for f in files_info if f[0] != 'A']
350 356
351 357
352 def getAllFilesInRevision(files_info): 358 def getAllFilesInRevision(files_info):
353 """Checks for existing files in the revision. 359 """Checks for existing files in the revision.
354 360
355 Anything that's A will require special treatment (either a merge or an 361 Anything that's A will require special treatment (either a merge or an
356 export + add) 362 export + add)
357 """ 363 """
358 return ['%s/%s' % (f[2], f[3]) for f in files_info] 364 return ['%s/%s' % (f[2], f[3]) for f in files_info]
359 365
M-A Ruel 2011/11/11 21:23:24 another empty line
James Hawkins 2011/11/11 21:50:25 Done.
366 def getBranchForMilestone(milestone):
367 """Queries omahaproxy.appspot.com for the branch number given |milestone|.
368 """
369 OMAHA_PROXY_URL = "http://omahaproxy.appspot.com"
370 request = urllib2.Request(OMAHA_PROXY_URL)
371 try:
372 response = urllib2.urlopen(request)
373 except urllib2.HTTPError, e:
374 print "Failed to query %s: %d" % (OMAHA_PROXY_URL, e.code)
375 return None
376
377 # Dictionary of [branch: major]. When searching for the appropriate branch
378 # matching |milestone|, all major versions that match are added to the
379 # dictionary. If all of the branches are the same, this branch value is
380 # returned; otherwise, the user is prompted to accept the largest branch
381 # value.
382 branch_dict = {}
383
384 # Slice the first line since it's column information text.
385 for line in response.readlines()[1:]:
386 # Version data is CSV.
387 parameters = string.split(line, ',')
388
389 # Version is the third parameter and consists of a quad of numbers separated
390 # by periods.
391 version = string.split(parameters[2], '.')
392 major = int(version[0], 10)
393 if major != milestone:
394 continue
395
396 # Branch number is the third value in the quad.
397 branch_dict[version[2]] = major
398
399 if not branch_dict:
400 # |milestone| not found.
401 print "Milestone provided is invalid"
402 return None
403
404 # The following returns a sorted list of the keys of |branch_dict|.
405 sorted_branches = sorted(branch_dict.iterkeys())
M-A Ruel 2011/11/11 21:23:24 sorted_branches = sorted(branch_dict)
James Hawkins 2011/11/11 21:50:25 Done.
406 branch = sorted_branches[0]
407
408 # If all keys match, the branch is the same for all platforms given
409 # |milestone|. This is the safe case, so return the branch.
410 if len(sorted_branches) == 1:
411 return branch
412
413 # Not all of the platforms have the same branch. Prompt the user and return
414 # the greatest (by value) branch on success.
415 if prompt("Not all platforms have the same branch number, "
416 "continue with branch %s?" % branch):
417 return branch
418
419 # User cancelled.
420 return None
421
M-A Ruel 2011/11/11 21:23:24 another empty line
James Hawkins 2011/11/11 21:50:25 Done.
360 def prompt(question): 422 def prompt(question):
361 while True: 423 while True:
362 print question + " [y|n]:", 424 print question + " [y|n]:",
363 answer = sys.stdin.readline() 425 answer = sys.stdin.readline()
364 if answer.lower().startswith('n'): 426 if answer.lower().startswith('n'):
365 return False 427 return False
366 elif answer.lower().startswith('y'): 428 elif answer.lower().startswith('y'):
367 return True 429 return True
368 430
369 431
370 def text_prompt(question, default): 432 def text_prompt(question, default):
371 print question + " [" + default + "]:" 433 print question + " [" + default + "]:"
372 answer = sys.stdin.readline() 434 answer = sys.stdin.readline()
373 if answer.strip() == "": 435 if answer.strip() == "":
374 return default 436 return default
375 return answer 437 return answer
376 438
377 439
378 def drover(options, args): 440 def drover(options, args):
379 revision = options.revert or options.merge 441 revision = options.revert or options.merge
380 442
381 # Initialize some variables used below. They can be overwritten by 443 # Initialize some variables used below. They can be overwritten by
382 # the drover.properties file. 444 # the drover.properties file.
383 BASE_URL = "svn://svn.chromium.org/chrome" 445 BASE_URL = "svn://svn.chromium.org/chrome"
384 TRUNK_URL = BASE_URL + "/trunk/src" 446 TRUNK_URL = BASE_URL + "/trunk/src"
385 BRANCH_URL = BASE_URL + "/branches/$branch/src" 447 BRANCH_URL = BASE_URL + "/branches/$branch/src"
386 SKIP_CHECK_WORKING = True 448 SKIP_CHECK_WORKING = True
387 PROMPT_FOR_AUTHOR = False 449 PROMPT_FOR_AUTHOR = False
388 450
451 # Translate a given milestone to the appropriate branch number.
452 if options.milestone:
453 options.branch = getBranchForMilestone(options.milestone)
laforge 2011/11/11 21:06:47 I'm not sure that you'll be able to set this value
James Hawkins 2011/11/11 21:11:41 Per-offline, manual tests show that this assignmen
454 if options.branch is None:
M-A Ruel 2011/11/11 21:23:24 if not options.branch:
James Hawkins 2011/11/11 21:50:25 Done.
455 return 1
456
389 DEFAULT_WORKING = "drover_" + str(revision) 457 DEFAULT_WORKING = "drover_" + str(revision)
390 if options.branch: 458 if options.branch:
391 DEFAULT_WORKING += ("_" + options.branch) 459 DEFAULT_WORKING += ("_" + options.branch)
392 460
393 if not isMinimumSVNVersion(1, 5): 461 if not isMinimumSVNVersion(1, 5):
394 print "You need to use at least SVN version 1.5.x" 462 print "You need to use at least SVN version 1.5.x"
395 return 1 463 return 1
396 464
397 # Override the default properties if there is a drover.properties file. 465 # Override the default properties if there is a drover.properties file.
398 global file_pattern_ 466 global file_pattern_
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 else: 583 else:
516 return 0 584 return 0
517 585
518 586
519 def main(): 587 def main():
520 option_parser = optparse.OptionParser(usage=USAGE % {"app": sys.argv[0]}) 588 option_parser = optparse.OptionParser(usage=USAGE % {"app": sys.argv[0]})
521 option_parser.add_option('-m', '--merge', type="int", 589 option_parser.add_option('-m', '--merge', type="int",
522 help='Revision to merge from trunk to branch') 590 help='Revision to merge from trunk to branch')
523 option_parser.add_option('-b', '--branch', 591 option_parser.add_option('-b', '--branch',
524 help='Branch to revert or merge from') 592 help='Branch to revert or merge from')
593 option_parser.add_option('-M', '--milestone', type="int",
594 help='Milestone to revert or merge from')
525 option_parser.add_option('-l', '--local', action='store_true', 595 option_parser.add_option('-l', '--local', action='store_true',
526 help='Local working copy to merge to') 596 help='Local working copy to merge to')
527 option_parser.add_option('-s', '--sbranch', 597 option_parser.add_option('-s', '--sbranch',
528 help='Source branch for merge') 598 help='Source branch for merge')
529 option_parser.add_option('-r', '--revert', type="int", 599 option_parser.add_option('-r', '--revert', type="int",
530 help='Revision to revert') 600 help='Revision to revert')
531 option_parser.add_option('-w', '--workdir', 601 option_parser.add_option('-w', '--workdir',
532 help='subdir to use for the revert') 602 help='subdir to use for the revert')
533 option_parser.add_option('-a', '--auditor', 603 option_parser.add_option('-a', '--auditor',
534 help='overrides the author for reviewer') 604 help='overrides the author for reviewer')
535 option_parser.add_option('', '--revertbot', action='store_true', 605 option_parser.add_option('', '--revertbot', action='store_true',
536 default=False) 606 default=False)
537 option_parser.add_option('', '--revertbot-commit', action='store_true', 607 option_parser.add_option('', '--revertbot-commit', action='store_true',
538 default=False) 608 default=False)
539 option_parser.add_option('', '--revertbot-reviewers') 609 option_parser.add_option('', '--revertbot-reviewers')
540 options, args = option_parser.parse_args() 610 options, args = option_parser.parse_args()
541 611
542 if not options.merge and not options.revert: 612 if not options.merge and not options.revert:
543 option_parser.error("You need at least --merge or --revert") 613 option_parser.error("You need at least --merge or --revert")
544 return 1 614 return 1
545 615
M-A Ruel 2011/11/11 21:23:24 optional: maybe: reference = bool(options.branch o
James Hawkins 2011/11/11 21:50:25 Done.
546 if options.merge and not options.branch and not options.local: 616 if (options.merge and not options.branch and not options.milestone and
617 not options.local):
547 option_parser.error("--merge requires either --branch or --local") 618 option_parser.error("--merge requires either --branch or --local")
M-A Ruel 2011/11/11 21:23:24 or --milestone ?
James Hawkins 2011/11/11 21:50:25 Done.
548 return 1 619 return 1
549 620
550 if options.local and (options.revert or options.branch): 621 if options.local and (options.revert or options.branch or options.milestone):
551 option_parser.error("--local cannot be used with --revert or --branch") 622 option_parser.error("--local cannot be used with --revert or --branch")
M-A Ruel 2011/11/11 21:23:24 or --milestone
James Hawkins 2011/11/11 21:50:25 Done.
552 return 1 623 return 1
553 624
625 if options.branch and options.milestone:
626 option_parser.error("--branch cannot be used with --milestone")
627 return 1
628
554 return drover(options, args) 629 return drover(options, args)
555 630
556 631
557 if __name__ == "__main__": 632 if __name__ == "__main__":
558 sys.exit(main()) 633 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