Factor out Changelist GetStatus() for eventual use by other tools
Pulls the logic for computing an issue's "status" - has LGTM, is in
CQ, etc. - out of the "git cl status" command itself, so that other
tools can get the status of a Changelist.
BUG=379849
R=iannucci@chromium.org
Review URL: https://codereview.chromium.org/555973005
git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@291928 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/git_cl.py b/git_cl.py
index 69af545..eeb7acf 100755
--- a/git_cl.py
+++ b/git_cl.py
@@ -839,6 +839,53 @@
author,
upstream=upstream_branch)
+ def GetStatus(self):
+ """Apply a rough heuristic to give a simple summary of an issue's review
+ or CQ status, assuming adherence to a common workflow.
+
+ Returns None if no issue for this branch, or one of the following keywords:
+ * 'error' - error from review tool (including deleted issues)
+ * 'unsent' - not sent for review
+ * 'waiting' - waiting for review
+ * 'reply' - waiting for owner to reply to review
+ * 'lgtm' - LGTM from at least one approved reviewer
+ * 'commit' - in the commit queue
+ * 'closed' - closed
+ """
+ if not self.GetIssue():
+ return None
+
+ try:
+ props = self.GetIssueProperties()
+ except urllib2.HTTPError:
+ return 'error'
+
+ if props.get('closed'):
+ # Issue is closed.
+ return 'closed'
+ if props.get('commit'):
+ # Issue is in the commit queue.
+ return 'commit'
+
+ try:
+ reviewers = self.GetApprovingReviewers()
+ except urllib2.HTTPError:
+ return 'error'
+
+ if reviewers:
+ # Was LGTM'ed.
+ return 'lgtm'
+
+ messages = props.get('messages') or []
+
+ if not messages:
+ # No message was sent.
+ return 'unsent'
+ if messages[-1]['sender'] != props.get('owner_email'):
+ # Non-LGTM reply from non-owner
+ return 'reply'
+ return 'waiting'
+
def RunHook(self, committing, may_prompt, verbose, change):
"""Calls sys.exit() if the hook fails; returns a HookResults otherwise."""
@@ -1218,6 +1265,19 @@
error_ok=False).strip()
+def color_for_status(status):
+ """Maps a Changelist status to color, for CMDstatus and other tools."""
+ return {
+ 'unsent': Fore.RED,
+ 'waiting': Fore.BLUE,
+ 'reply': Fore.YELLOW,
+ 'lgtm': Fore.GREEN,
+ 'commit': Fore.MAGENTA,
+ 'closed': Fore.CYAN,
+ 'error': Fore.WHITE,
+ }.get(status, Fore.WHITE)
+
+
def CMDstatus(parser, args):
"""Show status of changelists.
@@ -1277,36 +1337,13 @@
"""Fetches information for an issue and returns (branch, issue, color)."""
c = Changelist(branchref=b)
i = c.GetIssueURL()
- props = {}
- r = None
- if i:
- try:
- props = c.GetIssueProperties()
- r = c.GetApprovingReviewers() if i else None
- except urllib2.HTTPError:
- # The issue probably doesn't exist anymore.
- i += ' (broken)'
+ status = c.GetStatus()
+ color = color_for_status(status)
- msgs = props.get('messages') or []
+ if i and (not status or status == 'error'):
+ # The issue probably doesn't exist anymore.
+ i += ' (broken)'
- if not i:
- color = Fore.WHITE
- elif props.get('closed'):
- # Issue is closed.
- color = Fore.CYAN
- elif props.get('commit'):
- # Issue is in the commit queue.
- color = Fore.MAGENTA
- elif r:
- # Was LGTM'ed.
- color = Fore.GREEN
- elif not msgs:
- # No message was sent.
- color = Fore.RED
- elif msgs[-1]['sender'] != props.get('owner_email'):
- color = Fore.YELLOW
- else:
- color = Fore.BLUE
output.put((b, i, color))
# Process one branch synchronously to work through authentication, then