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 # Copyright (C) 2008 Evan Martin <martine@danga.com> | 6 # Copyright (C) 2008 Evan Martin <martine@danga.com> |
7 | 7 |
8 """A git-command for integrating reviews on Rietveld.""" | 8 """A git-command for integrating reviews on Rietveld.""" |
9 | 9 |
10 import difflib | 10 import difflib |
11 from distutils.version import LooseVersion | 11 from distutils.version import LooseVersion |
12 import json | 12 import json |
13 import logging | 13 import logging |
14 import optparse | 14 import optparse |
15 import os | 15 import os |
16 import Queue | |
16 import re | 17 import re |
17 import stat | 18 import stat |
18 import sys | 19 import sys |
19 import textwrap | 20 import textwrap |
21 import threading | |
20 import urllib2 | 22 import urllib2 |
21 import urlparse | 23 import urlparse |
22 | 24 |
23 try: | 25 try: |
24 import readline # pylint: disable=F0401,W0611 | 26 import readline # pylint: disable=F0401,W0611 |
25 except ImportError: | 27 except ImportError: |
26 pass | 28 pass |
27 | 29 |
28 | 30 |
29 from third_party import colorama | 31 from third_party import colorama |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
405 self.LazyUpdateIfNeeded() | 407 self.LazyUpdateIfNeeded() |
406 return RunGit(['config', param], **kwargs).strip() | 408 return RunGit(['config', param], **kwargs).strip() |
407 | 409 |
408 | 410 |
409 def ShortBranchName(branch): | 411 def ShortBranchName(branch): |
410 """Convert a name like 'refs/heads/foo' to just 'foo'.""" | 412 """Convert a name like 'refs/heads/foo' to just 'foo'.""" |
411 return branch.replace('refs/heads/', '') | 413 return branch.replace('refs/heads/', '') |
412 | 414 |
413 | 415 |
414 class Changelist(object): | 416 class Changelist(object): |
415 def __init__(self, branchref=None): | 417 def __init__(self, branchref=None, issue=None): |
416 # Poke settings so we get the "configure your server" message if necessary. | 418 # Poke settings so we get the "configure your server" message if necessary. |
417 global settings | 419 global settings |
418 if not settings: | 420 if not settings: |
419 # Happens when git_cl.py is used as a utility library. | 421 # Happens when git_cl.py is used as a utility library. |
420 settings = Settings() | 422 settings = Settings() |
421 settings.GetDefaultServerUrl() | 423 settings.GetDefaultServerUrl() |
422 self.branchref = branchref | 424 self.branchref = branchref |
423 if self.branchref: | 425 if self.branchref: |
424 self.branch = ShortBranchName(self.branchref) | 426 self.branch = ShortBranchName(self.branchref) |
425 else: | 427 else: |
426 self.branch = None | 428 self.branch = None |
427 self.rietveld_server = None | 429 self.rietveld_server = None |
428 self.upstream_branch = None | 430 self.upstream_branch = None |
429 self.has_issue = False | 431 self.lookedup_issue = False |
430 self.issue = None | 432 self.issue = issue or None |
431 self.has_description = False | 433 self.has_description = False |
432 self.description = None | 434 self.description = None |
433 self.has_patchset = False | 435 self.lookedup_patchset = False |
434 self.patchset = None | 436 self.patchset = None |
435 self._rpc_server = None | 437 self._rpc_server = None |
436 self.cc = None | 438 self.cc = None |
437 self.watchers = () | 439 self.watchers = () |
438 self._remote = None | 440 self._remote = None |
441 self._props = None | |
439 | 442 |
440 def GetCCList(self): | 443 def GetCCList(self): |
441 """Return the users cc'd on this CL. | 444 """Return the users cc'd on this CL. |
442 | 445 |
443 Return is a string suitable for passing to gcl with the --cc flag. | 446 Return is a string suitable for passing to gcl with the --cc flag. |
444 """ | 447 """ |
445 if self.cc is None: | 448 if self.cc is None: |
446 base_cc = settings .GetDefaultCCList() | 449 base_cc = settings .GetDefaultCCList() |
447 more_cc = ','.join(self.watchers) | 450 more_cc = ','.join(self.watchers) |
448 self.cc = ','.join(filter(None, (base_cc, more_cc))) or '' | 451 self.cc = ','.join(filter(None, (base_cc, more_cc))) or '' |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
594 def GetRemoteUrl(self): | 597 def GetRemoteUrl(self): |
595 """Return the configured remote URL, e.g. 'git://example.org/foo.git/'. | 598 """Return the configured remote URL, e.g. 'git://example.org/foo.git/'. |
596 | 599 |
597 Returns None if there is no remote. | 600 Returns None if there is no remote. |
598 """ | 601 """ |
599 remote, _ = self.GetRemoteBranch() | 602 remote, _ = self.GetRemoteBranch() |
600 return RunGit(['config', 'remote.%s.url' % remote], error_ok=True).strip() | 603 return RunGit(['config', 'remote.%s.url' % remote], error_ok=True).strip() |
601 | 604 |
602 def GetIssue(self): | 605 def GetIssue(self): |
603 """Returns the issue number as a int or None if not set.""" | 606 """Returns the issue number as a int or None if not set.""" |
604 if not self.has_issue: | 607 if self.issue is None and not self.lookedup_issue: |
605 issue = RunGit(['config', self._IssueSetting()], error_ok=True).strip() | 608 issue = RunGit(['config', self._IssueSetting()], error_ok=True).strip() |
606 if issue: | 609 self.issue = int(issue) or None if issue else None |
607 self.issue = int(issue) | 610 self.lookedup_issue = True |
608 else: | |
609 self.issue = None | |
610 self.has_issue = True | |
611 return self.issue | 611 return self.issue |
612 | 612 |
613 def GetRietveldServer(self): | 613 def GetRietveldServer(self): |
614 if not self.rietveld_server: | 614 if not self.rietveld_server: |
615 # If we're on a branch then get the server potentially associated | 615 # If we're on a branch then get the server potentially associated |
616 # with that branch. | 616 # with that branch. |
617 if self.GetIssue(): | 617 if self.GetIssue(): |
618 self.rietveld_server = gclient_utils.UpgradeToHttps(RunGit( | 618 self.rietveld_server = gclient_utils.UpgradeToHttps(RunGit( |
619 ['config', self._RietveldServer()], error_ok=True).strip()) | 619 ['config', self._RietveldServer()], error_ok=True).strip()) |
620 if not self.rietveld_server: | 620 if not self.rietveld_server: |
(...skipping 28 matching lines...) Expand all Loading... | |
649 '\nFailed to fetch issue description. HTTP error ' + e.code) | 649 '\nFailed to fetch issue description. HTTP error ' + e.code) |
650 self.has_description = True | 650 self.has_description = True |
651 if pretty: | 651 if pretty: |
652 wrapper = textwrap.TextWrapper() | 652 wrapper = textwrap.TextWrapper() |
653 wrapper.initial_indent = wrapper.subsequent_indent = ' ' | 653 wrapper.initial_indent = wrapper.subsequent_indent = ' ' |
654 return wrapper.fill(self.description) | 654 return wrapper.fill(self.description) |
655 return self.description | 655 return self.description |
656 | 656 |
657 def GetPatchset(self): | 657 def GetPatchset(self): |
658 """Returns the patchset number as a int or None if not set.""" | 658 """Returns the patchset number as a int or None if not set.""" |
659 if not self.has_patchset: | 659 if self.patchset is None and not self.lookedup_patchset: |
660 patchset = RunGit(['config', self._PatchsetSetting()], | 660 patchset = RunGit(['config', self._PatchsetSetting()], |
661 error_ok=True).strip() | 661 error_ok=True).strip() |
662 if patchset: | 662 self.patchset = int(patchset) or None if patchset else None |
663 self.patchset = int(patchset) | 663 self.lookedup_patchset = True |
664 else: | |
665 self.patchset = None | |
666 self.has_patchset = True | |
667 return self.patchset | 664 return self.patchset |
668 | 665 |
669 def SetPatchset(self, patchset): | 666 def SetPatchset(self, patchset): |
670 """Set this branch's patchset. If patchset=0, clears the patchset.""" | 667 """Set this branch's patchset. If patchset=0, clears the patchset.""" |
671 if patchset: | 668 if patchset: |
672 RunGit(['config', self._PatchsetSetting(), str(patchset)]) | 669 RunGit(['config', self._PatchsetSetting(), str(patchset)]) |
670 self.patchset = patchset | |
673 else: | 671 else: |
674 RunGit(['config', '--unset', self._PatchsetSetting()], | 672 RunGit(['config', '--unset', self._PatchsetSetting()], |
675 stderr=subprocess2.PIPE, error_ok=True) | 673 stderr=subprocess2.PIPE, error_ok=True) |
676 self.has_patchset = False | 674 self.patchset = None |
677 | 675 |
678 def GetMostRecentPatchset(self, issue): | 676 def GetMostRecentPatchset(self): |
679 return self.RpcServer().get_issue_properties( | 677 return self.GetIssueProperties()['patchsets'][-1] |
680 int(issue), False)['patchsets'][-1] | |
681 | 678 |
682 def GetPatchSetDiff(self, issue, patchset): | 679 def GetPatchSetDiff(self, issue, patchset): |
683 return self.RpcServer().get( | 680 return self.RpcServer().get( |
684 '/download/issue%s_%s.diff' % (issue, patchset)) | 681 '/download/issue%s_%s.diff' % (issue, patchset)) |
685 | 682 |
683 def GetIssueProperties(self): | |
684 if self._props is None: | |
685 issue = self.GetIssue() | |
686 if not issue: | |
687 self._props = {} | |
688 else: | |
689 self._props = self.RpcServer().get_issue_properties(issue, True) | |
690 return self._props | |
691 | |
686 def GetApprovingReviewers(self): | 692 def GetApprovingReviewers(self): |
687 return get_approving_reviewers( | 693 return get_approving_reviewers(self.GetIssueProperties()) |
688 self.RpcServer().get_issue_properties(self.GetIssue(), True)) | |
689 | 694 |
690 def SetIssue(self, issue): | 695 def SetIssue(self, issue): |
691 """Set this branch's issue. If issue=0, clears the issue.""" | 696 """Set this branch's issue. If issue=0, clears the issue.""" |
692 if issue: | 697 if issue: |
698 self.issue = issue | |
693 RunGit(['config', self._IssueSetting(), str(issue)]) | 699 RunGit(['config', self._IssueSetting(), str(issue)]) |
694 if self.rietveld_server: | 700 if self.rietveld_server: |
695 RunGit(['config', self._RietveldServer(), self.rietveld_server]) | 701 RunGit(['config', self._RietveldServer(), self.rietveld_server]) |
696 else: | 702 else: |
697 RunGit(['config', '--unset', self._IssueSetting()]) | 703 RunGit(['config', '--unset', self._IssueSetting()]) |
698 self.SetPatchset(0) | 704 self.issue = None |
699 self.has_issue = False | 705 self.SetPatchset(None) |
700 | 706 |
701 def GetChange(self, upstream_branch, author): | 707 def GetChange(self, upstream_branch, author): |
702 if not self.GitSanityChecks(upstream_branch): | 708 if not self.GitSanityChecks(upstream_branch): |
703 DieWithError('\nGit sanity check failure') | 709 DieWithError('\nGit sanity check failure') |
704 | 710 |
705 env = os.environ.copy() | 711 env = os.environ.copy() |
706 # 'cat' is a magical git string that disables pagers on all platforms. | 712 # 'cat' is a magical git string that disables pagers on all platforms. |
707 env['GIT_PAGER'] = 'cat' | 713 env['GIT_PAGER'] = 'cat' |
708 | 714 |
709 root = RunCommand(['git', 'rev-parse', '--show-cdup'], env=env).strip() | 715 root = RunCommand(['git', 'rev-parse', '--show-cdup'], env=env).strip() |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1057 else: | 1063 else: |
1058 print("Setting base-url to %s" % args[0]) | 1064 print("Setting base-url to %s" % args[0]) |
1059 return RunGit(['config', 'branch.%s.base-url' % branch, args[0]], | 1065 return RunGit(['config', 'branch.%s.base-url' % branch, args[0]], |
1060 error_ok=False).strip() | 1066 error_ok=False).strip() |
1061 | 1067 |
1062 | 1068 |
1063 def CMDstatus(parser, args): | 1069 def CMDstatus(parser, args): |
1064 """show status of changelists""" | 1070 """show status of changelists""" |
1065 parser.add_option('--field', | 1071 parser.add_option('--field', |
1066 help='print only specific field (desc|id|patch|url)') | 1072 help='print only specific field (desc|id|patch|url)') |
1073 parser.add_option('-f', '--fast', action='store_true', | |
1074 help='Do not retrieve review status') | |
1067 (options, args) = parser.parse_args(args) | 1075 (options, args) = parser.parse_args(args) |
1068 | 1076 |
1069 if options.field: | 1077 if options.field: |
1070 cl = Changelist() | 1078 cl = Changelist() |
1071 if options.field.startswith('desc'): | 1079 if options.field.startswith('desc'): |
1072 print cl.GetDescription() | 1080 print cl.GetDescription() |
1073 elif options.field == 'id': | 1081 elif options.field == 'id': |
1074 issueid = cl.GetIssue() | 1082 issueid = cl.GetIssue() |
1075 if issueid: | 1083 if issueid: |
1076 print issueid | 1084 print issueid |
1077 elif options.field == 'patch': | 1085 elif options.field == 'patch': |
1078 patchset = cl.GetPatchset() | 1086 patchset = cl.GetPatchset() |
1079 if patchset: | 1087 if patchset: |
1080 print patchset | 1088 print patchset |
1081 elif options.field == 'url': | 1089 elif options.field == 'url': |
1082 url = cl.GetIssueURL() | 1090 url = cl.GetIssueURL() |
1083 if url: | 1091 if url: |
1084 print url | 1092 print url |
1085 return 0 | 1093 return 0 |
1086 | 1094 |
1087 branches = RunGit(['for-each-ref', '--format=%(refname)', 'refs/heads']) | 1095 branches = RunGit(['for-each-ref', '--format=%(refname)', 'refs/heads']) |
1088 if not branches: | 1096 if not branches: |
1089 print('No local branch found.') | 1097 print('No local branch found.') |
1090 return 0 | 1098 return 0 |
1091 | 1099 |
1092 changes = (Changelist(branchref=b) for b in branches.splitlines()) | 1100 changes = (Changelist(branchref=b) for b in branches.splitlines()) |
1093 branches = dict((c.GetBranch(), c.GetIssueURL()) for c in changes) | 1101 branches = dict((c.GetBranch(), c.GetIssueURL()) for c in changes) |
1094 alignment = max(5, max(len(b) for b in branches)) | 1102 alignment = max(5, max(len(b) for b in branches)) |
1095 print 'Branches associated with reviews:' | 1103 print 'Branches associated with reviews:' |
1104 # Adhoc thread pool to request data concurrently. | |
1105 output = Queue.Queue() | |
1106 | |
1107 # Silence upload.py otherwise it becomes unweldly. | |
1108 upload.verbosity = 0 | |
1109 | |
1110 if not options.fast: | |
1111 def fetch(b): | |
1112 c = Changelist(branchref=b) | |
1113 i = c.GetIssueURL() | |
1114 try: | |
1115 props = c.GetIssueProperties() | |
1116 r = c.GetApprovingReviewers() if i else None | |
1117 if not props.get('messages'): | |
1118 r = None | |
1119 except urllib2.HTTPError: | |
1120 # The issue probably doesn't exist anymore. | |
1121 i += ' (broken)' | |
1122 r = None | |
1123 output.put((b, i, r)) | |
1124 | |
1125 threads = [threading.Thread(target=fetch, args=(b,)) for b in branches] | |
1126 for t in threads: | |
1127 t.daemon = True | |
1128 t.start() | |
1129 else: | |
1130 # Do not use GetApprovingReviewers(), since it requires an HTTP request. | |
1131 for b in branches: | |
1132 c = Changelist(branchref=b) | |
1133 output.put((b, c.GetIssue(), None)) | |
1134 | |
1135 tmp = {} | |
1136 alignment = max(5, max(len(ShortBranchName(b)) for b in branches)) | |
1096 for branch in sorted(branches): | 1137 for branch in sorted(branches): |
1097 print " %*s: %s" % (alignment, branch, branches[branch]) | 1138 while branch not in tmp: |
1139 b, i, r = output.get() | |
1140 tmp[b] = (i, r) | |
1141 issue, reviewers = tmp.pop(branch) | |
1142 if not issue: | |
1143 color = Fore.WHITE | |
1144 elif reviewers: | |
1145 # Was approved. | |
1146 color = Fore.GREEN | |
1147 elif reviewers is None: | |
1148 # No message was sent. | |
1149 color = Fore.RED | |
1150 else: | |
1151 color = Fore.BLUE | |
1152 print ' %*s: %s%s%s' % ( | |
1153 alignment, ShortBranchName(branch), color, issue, Fore.RESET) | |
1154 | |
1098 cl = Changelist() | 1155 cl = Changelist() |
1099 print | 1156 print |
1100 print 'Current branch:', | 1157 print 'Current branch:', |
1101 if not cl.GetIssue(): | 1158 if not cl.GetIssue(): |
1102 print 'no issue assigned.' | 1159 print 'no issue assigned.' |
1103 return 0 | 1160 return 0 |
1104 print cl.GetBranch() | 1161 print cl.GetBranch() |
1105 print 'Issue number: %s (%s)' % (cl.GetIssue(), cl.GetIssueURL()) | 1162 print 'Issue number: %s (%s)' % (cl.GetIssue(), cl.GetIssueURL()) |
1106 print 'Issue description:' | 1163 print 'Issue description:' |
1107 print cl.GetDescription(pretty=True) | 1164 print cl.GetDescription(pretty=True) |
(...skipping 21 matching lines...) Expand all Loading... | |
1129 | 1186 |
1130 | 1187 |
1131 def CMDcomments(parser, args): | 1188 def CMDcomments(parser, args): |
1132 """show review comments of the current changelist""" | 1189 """show review comments of the current changelist""" |
1133 (_, args) = parser.parse_args(args) | 1190 (_, args) = parser.parse_args(args) |
1134 if args: | 1191 if args: |
1135 parser.error('Unsupported argument: %s' % args) | 1192 parser.error('Unsupported argument: %s' % args) |
1136 | 1193 |
1137 cl = Changelist() | 1194 cl = Changelist() |
1138 if cl.GetIssue(): | 1195 if cl.GetIssue(): |
1139 data = cl.RpcServer().get_issue_properties(cl.GetIssue(), True) | 1196 data = cl.GetIssueProperties() |
1140 for message in sorted(data['messages'], key=lambda x: x['date']): | 1197 for message in sorted(data['messages'], key=lambda x: x['date']): |
1141 if message['disapproval']: | 1198 if message['disapproval']: |
1142 color = Fore.RED | 1199 color = Fore.RED |
1143 elif message['approval']: | 1200 elif message['approval']: |
1144 color = Fore.GREEN | 1201 color = Fore.GREEN |
1145 elif message['sender'] == data['owner_email']: | 1202 elif message['sender'] == data['owner_email']: |
1146 color = Fore.MAGENTA | 1203 color = Fore.MAGENTA |
1147 else: | 1204 else: |
1148 color = Fore.BLUE | 1205 color = Fore.BLUE |
1149 print '\n%s%s %s%s' % ( | 1206 print '\n%s%s %s%s' % ( |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1427 hook_results = cl.RunHook(committing=False, | 1484 hook_results = cl.RunHook(committing=False, |
1428 may_prompt=not options.force, | 1485 may_prompt=not options.force, |
1429 verbose=options.verbose, | 1486 verbose=options.verbose, |
1430 change=change) | 1487 change=change) |
1431 if not hook_results.should_continue(): | 1488 if not hook_results.should_continue(): |
1432 return 1 | 1489 return 1 |
1433 if not options.reviewers and hook_results.reviewers: | 1490 if not options.reviewers and hook_results.reviewers: |
1434 options.reviewers = hook_results.reviewers.split(',') | 1491 options.reviewers = hook_results.reviewers.split(',') |
1435 | 1492 |
1436 if cl.GetIssue(): | 1493 if cl.GetIssue(): |
1437 latest_patchset = cl.GetMostRecentPatchset(cl.GetIssue()) | 1494 latest_patchset = cl.GetMostRecentPatchset() |
1438 local_patchset = cl.GetPatchset() | 1495 local_patchset = cl.GetPatchset() |
1439 if latest_patchset and local_patchset and local_patchset != latest_patchset: | 1496 if latest_patchset and local_patchset and local_patchset != latest_patchset: |
1440 print ('The last upload made from this repository was patchset #%d but ' | 1497 print ('The last upload made from this repository was patchset #%d but ' |
1441 'the most recent patchset on the server is #%d.' | 1498 'the most recent patchset on the server is #%d.' |
1442 % (local_patchset, latest_patchset)) | 1499 % (local_patchset, latest_patchset)) |
1443 print ('Uploading will still work, but if you\'ve uploaded to this issue ' | 1500 print ('Uploading will still work, but if you\'ve uploaded to this issue ' |
1444 'from another machine or branch the patch you\'re uploading now ' | 1501 'from another machine or branch the patch you\'re uploading now ' |
1445 'might not include those changes.') | 1502 'might not include those changes.') |
1446 ask_for_data('About to upload; enter to confirm.') | 1503 ask_for_data('About to upload; enter to confirm.') |
1447 | 1504 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1666 return 1 | 1723 return 1 |
1667 viewvc_url = settings.GetViewVCUrl() | 1724 viewvc_url = settings.GetViewVCUrl() |
1668 if viewvc_url and revision: | 1725 if viewvc_url and revision: |
1669 change_desc.append_footer('Committed: ' + viewvc_url + revision) | 1726 change_desc.append_footer('Committed: ' + viewvc_url + revision) |
1670 elif revision: | 1727 elif revision: |
1671 change_desc.append_footer('Committed: ' + revision) | 1728 change_desc.append_footer('Committed: ' + revision) |
1672 print ('Closing issue ' | 1729 print ('Closing issue ' |
1673 '(you may be prompted for your codereview password)...') | 1730 '(you may be prompted for your codereview password)...') |
1674 cl.UpdateDescription(change_desc.description) | 1731 cl.UpdateDescription(change_desc.description) |
1675 cl.CloseIssue() | 1732 cl.CloseIssue() |
1676 props = cl.RpcServer().get_issue_properties(cl.GetIssue(), False) | 1733 props = cl.GetIssueProperties() |
1677 patch_num = len(props['patchsets']) | 1734 patch_num = len(props['patchsets']) |
1678 comment = "Committed patchset #%d manually as r%s" % (patch_num, revision) | 1735 comment = "Committed patchset #%d manually as r%s" % (patch_num, revision) |
1679 comment += ' (presubmit successful).' if not options.bypass_hooks else '.' | 1736 comment += ' (presubmit successful).' if not options.bypass_hooks else '.' |
1680 cl.RpcServer().add_comment(cl.GetIssue(), comment) | 1737 cl.RpcServer().add_comment(cl.GetIssue(), comment) |
1681 cl.SetIssue(0) | 1738 cl.SetIssue(None) |
iannucci
2013/07/23 21:19:25
if you git cl issue 0, will that still do the righ
M-A Ruel
2013/07/23 23:22:29
Yes, tested.
| |
1682 | 1739 |
1683 if retcode == 0: | 1740 if retcode == 0: |
1684 hook = POSTUPSTREAM_HOOK_PATTERN % cmd | 1741 hook = POSTUPSTREAM_HOOK_PATTERN % cmd |
1685 if os.path.isfile(hook): | 1742 if os.path.isfile(hook): |
1686 RunCommand([hook, base_branch], error_ok=True) | 1743 RunCommand([hook, base_branch], error_ok=True) |
1687 | 1744 |
1688 return 0 | 1745 return 0 |
1689 | 1746 |
1690 | 1747 |
1691 @usage('[upstream branch to apply against]') | 1748 @usage('[upstream branch to apply against]') |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1730 if len(args) != 1: | 1787 if len(args) != 1: |
1731 parser.print_help() | 1788 parser.print_help() |
1732 return 1 | 1789 return 1 |
1733 issue_arg = args[0] | 1790 issue_arg = args[0] |
1734 | 1791 |
1735 # TODO(maruel): Use apply_issue.py | 1792 # TODO(maruel): Use apply_issue.py |
1736 # TODO(ukai): use gerrit-cherry-pick for gerrit repository? | 1793 # TODO(ukai): use gerrit-cherry-pick for gerrit repository? |
1737 | 1794 |
1738 if issue_arg.isdigit(): | 1795 if issue_arg.isdigit(): |
1739 # Input is an issue id. Figure out the URL. | 1796 # Input is an issue id. Figure out the URL. |
1740 cl = Changelist() | |
1741 issue = int(issue_arg) | 1797 issue = int(issue_arg) |
1742 patchset = cl.GetMostRecentPatchset(issue) | 1798 cl = Changelist(issue) |
1799 patchset = cl.GetMostRecentPatchset() | |
1743 patch_data = cl.GetPatchSetDiff(issue, patchset) | 1800 patch_data = cl.GetPatchSetDiff(issue, patchset) |
1744 else: | 1801 else: |
1745 # Assume it's a URL to the patch. Default to https. | 1802 # Assume it's a URL to the patch. Default to https. |
1746 issue_url = gclient_utils.UpgradeToHttps(issue_arg) | 1803 issue_url = gclient_utils.UpgradeToHttps(issue_arg) |
1747 match = re.match(r'.*?/issue(\d+)_(\d+).diff', issue_url) | 1804 match = re.match(r'.*?/issue(\d+)_(\d+).diff', issue_url) |
1748 if not match: | 1805 if not match: |
1749 DieWithError('Must pass an issue ID or full URL for ' | 1806 DieWithError('Must pass an issue ID or full URL for ' |
1750 '\'Download raw patch set\'') | 1807 '\'Download raw patch set\'') |
1751 issue = int(match.group(1)) | 1808 issue = int(match.group(1)) |
1752 patchset = int(match.group(2)) | 1809 patchset = int(match.group(2)) |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1939 if any('triggered' in b for b in builders_and_tests): | 1996 if any('triggered' in b for b in builders_and_tests): |
1940 print >> sys.stderr, ( | 1997 print >> sys.stderr, ( |
1941 'ERROR You are trying to send a job to a triggered bot. This type of' | 1998 'ERROR You are trying to send a job to a triggered bot. This type of' |
1942 ' bot requires an\ninitial job from a parent (usually a builder). ' | 1999 ' bot requires an\ninitial job from a parent (usually a builder). ' |
1943 'Instead send your job to the parent.\n' | 2000 'Instead send your job to the parent.\n' |
1944 'Bot list: %s' % builders_and_tests) | 2001 'Bot list: %s' % builders_and_tests) |
1945 return 1 | 2002 return 1 |
1946 | 2003 |
1947 patchset = cl.GetPatchset() | 2004 patchset = cl.GetPatchset() |
1948 if not cl.GetPatchset(): | 2005 if not cl.GetPatchset(): |
1949 patchset = cl.GetMostRecentPatchset(cl.GetIssue()) | 2006 patchset = cl.GetMostRecentPatchset() |
1950 | 2007 |
1951 cl.RpcServer().trigger_try_jobs( | 2008 cl.RpcServer().trigger_try_jobs( |
1952 cl.GetIssue(), patchset, options.name, options.clobber, options.revision, | 2009 cl.GetIssue(), patchset, options.name, options.clobber, options.revision, |
1953 builders_and_tests) | 2010 builders_and_tests) |
1954 print('Tried jobs on:') | 2011 print('Tried jobs on:') |
1955 length = max(len(builder) for builder in builders_and_tests) | 2012 length = max(len(builder) for builder in builders_and_tests) |
1956 for builder in sorted(builders_and_tests): | 2013 for builder in sorted(builders_and_tests): |
1957 print ' %*s: %s' % (length, builder, ','.join(builders_and_tests[builder])) | 2014 print ' %*s: %s' % (length, builder, ','.join(builders_and_tests[builder])) |
1958 return 0 | 2015 return 0 |
1959 | 2016 |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2177 GenUsage(parser, 'help') | 2234 GenUsage(parser, 'help') |
2178 return CMDhelp(parser, argv) | 2235 return CMDhelp(parser, argv) |
2179 | 2236 |
2180 | 2237 |
2181 if __name__ == '__main__': | 2238 if __name__ == '__main__': |
2182 # These affect sys.stdout so do it outside of main() to simplify mocks in | 2239 # These affect sys.stdout so do it outside of main() to simplify mocks in |
2183 # unit testing. | 2240 # unit testing. |
2184 fix_encoding.fix_encoding() | 2241 fix_encoding.fix_encoding() |
2185 colorama.init() | 2242 colorama.init() |
2186 sys.exit(main(sys.argv[1:])) | 2243 sys.exit(main(sys.argv[1:])) |
OLD | NEW |