Chromium Code Reviews| Index: git_cl.py |
| diff --git a/git_cl.py b/git_cl.py |
| index db9823042e62a91a1e8258e007cc5a90380c162b..c11da24cc82bbb09c56bdb687d339352bb509ec4 100755 |
| --- a/git_cl.py |
| +++ b/git_cl.py |
| @@ -13,10 +13,12 @@ import json |
| import logging |
| import optparse |
| import os |
| +import Queue |
| import re |
| import stat |
| import sys |
| import textwrap |
| +import threading |
| import urllib2 |
| import urlparse |
| @@ -436,6 +438,7 @@ class Changelist(object): |
| self.cc = None |
| self.watchers = () |
| self._remote = None |
| + self._props = None |
| def GetCCList(self): |
| """Return the users cc'd on this CL. |
| @@ -676,16 +679,23 @@ or verify this branch is set up to track another (via the --track argument to |
| self.has_patchset = False |
| def GetMostRecentPatchset(self, issue): |
|
iannucci
2013/07/23 02:07:28
issue is unused?
M-A Ruel
2013/07/23 14:32:42
Oops. Did a bit of surgery to fix the thing.
|
| - return self.RpcServer().get_issue_properties( |
| - int(issue), False)['patchsets'][-1] |
| + return self.GetIssueProperties()['patchsets'][-1] |
| def GetPatchSetDiff(self, issue, patchset): |
| return self.RpcServer().get( |
| '/download/issue%s_%s.diff' % (issue, patchset)) |
| + def GetIssueProperties(self): |
| + if self._props is None: |
| + if not self.GetIssue(): |
| + self._props = {} |
| + else: |
| + self._props = self.RpcServer().get_issue_properties( |
| + self.GetIssue(), True) |
| + return self._props |
| + |
| def GetApprovingReviewers(self): |
| - return get_approving_reviewers( |
| - self.RpcServer().get_issue_properties(self.GetIssue(), True)) |
| + return get_approving_reviewers(self.GetIssueProperties()) |
| def SetIssue(self, issue): |
| """Set this branch's issue. If issue=0, clears the issue.""" |
| @@ -1064,6 +1074,8 @@ def CMDstatus(parser, args): |
| """show status of changelists""" |
| parser.add_option('--field', |
| help='print only specific field (desc|id|patch|url)') |
| + parser.add_option('-f', '--fast', action='store_true', |
| + help='Do not retrieve review status') |
| (options, args) = parser.parse_args(args) |
| if options.field: |
| @@ -1093,8 +1105,57 @@ def CMDstatus(parser, args): |
| branches = dict((c.GetBranch(), c.GetIssueURL()) for c in changes) |
| alignment = max(5, max(len(b) for b in branches)) |
| print 'Branches associated with reviews:' |
| + # Adhoc thread pool to request data concurrently. |
| + output = Queue.Queue() |
| + |
| + # Silence upload.py otherwise it becomes unweldly. |
| + upload.verbosity = 0 |
| + |
| + if not options.fast: |
| + def fetch(b): |
| + c = Changelist(branchref=b) |
| + i = c.GetIssueURL() |
| + try: |
| + props = c.GetIssueProperties() |
| + r = c.GetApprovingReviewers() if i else None |
| + if not props.get('messages'): |
| + r = None |
| + except urllib2.HTTPError: |
| + # The issue probably doesn't exist anymore. |
| + i += ' (broken)' |
| + r = None |
| + output.put((b, i, r)) |
| + |
| + threads = [threading.Thread(target=fetch, args=(b,)) for b in branches] |
| + for t in threads: |
| + t.daemon = True |
| + t.start() |
| + else: |
| + # Do not use GetApprovingReviewers(), since it requires an HTTP request. |
| + for b in branches: |
| + c = Changelist(branchref=b) |
| + output.put((b, c.GetIssue(), None)) |
| + |
| + tmp = {} |
| + alignment = max(5, max(len(ShortBranchName(b)) for b in branches)) |
| for branch in sorted(branches): |
| - print " %*s: %s" % (alignment, branch, branches[branch]) |
| + while branch not in tmp: |
| + b, i, r = output.get() |
| + tmp[b] = (i, r) |
| + issue, reviewers = tmp.pop(branch) |
| + if not issue: |
| + color = Fore.WHITE |
| + elif reviewers: |
| + # Was approved. |
| + color = Fore.GREEN |
| + elif reviewers is None: |
| + # No message was sent. |
| + color = Fore.RED |
| + else: |
| + color = Fore.BLUE |
| + print ' %*s: %s%s%s' % ( |
| + alignment, ShortBranchName(branch), color, issue, Fore.RESET) |
| + |
| cl = Changelist() |
| print 'Current branch:', |
| @@ -1136,7 +1197,7 @@ def CMDcomments(parser, args): |
| cl = Changelist() |
| if cl.GetIssue(): |
| - data = cl.RpcServer().get_issue_properties(cl.GetIssue(), True) |
| + data = cl.GetIssueProperties() |
| for message in sorted(data['messages'], key=lambda x: x['date']): |
| if message['disapproval']: |
| color = Fore.RED |
| @@ -1673,7 +1734,7 @@ def SendUpstream(parser, args, cmd): |
| '(you may be prompted for your codereview password)...') |
| cl.UpdateDescription(change_desc.description) |
| cl.CloseIssue() |
| - props = cl.RpcServer().get_issue_properties(cl.GetIssue(), False) |
| + props = cl.GetIssueProperties() |
| patch_num = len(props['patchsets']) |
| comment = "Committed patchset #%d manually as r%s" % (patch_num, revision) |
| comment += ' (presubmit successful).' if not options.bypass_hooks else '.' |