Index: git_cl.py |
diff --git a/git_cl.py b/git_cl.py |
index 41bbb9800ecf68e8a24e5e9b0f9ce055009f8074..f10c196b93a83db5a5d2015195419feced1f9f52 100755 |
--- a/git_cl.py |
+++ b/git_cl.py |
@@ -1448,6 +1448,14 @@ class Changelist(object): |
def GetStatus(self): |
return self._codereview_impl.GetStatus() |
+ def IsOpen(self): |
+ return self._codereview_impl.IsOpen() |
+ |
+ def GetCQState(self): |
+ state = self._codereview_impl.GetCQState() |
+ assert state in _CQState.ALL_STATES |
+ return state |
+ |
def GetCodereviewServer(self): |
return self._codereview_impl.GetCodereviewServer() |
@@ -1483,6 +1491,14 @@ class _ChangelistCodereviewBase(object): |
""" |
raise NotImplementedError() |
+ def IsOpen(self): |
+ """Returns True iff the issue is open.""" |
+ raise NotImplementedError() |
+ |
+ def GetCQState(self): |
+ """Returns CQ state (see _CQState).""" |
+ raise NotImplementedError() |
+ |
def GetCodereviewServer(self): |
"""Returns server URL without end slash, like "https://codereview.com".""" |
raise NotImplementedError() |
@@ -1681,11 +1697,9 @@ class _RietveldChangelistImpl(_ChangelistCodereviewBase): |
except urllib2.HTTPError: |
return 'error' |
- if props.get('closed'): |
- # Issue is closed. |
+ if not self.IsOpen(): |
return 'closed' |
- if props.get('commit') and not props.get('cq_dry_run', False): |
- # Issue is in the commit queue. |
+ if self.GetCQState() == _CQState.COMMIT: |
return 'commit' |
try: |
@@ -1719,6 +1733,20 @@ class _RietveldChangelistImpl(_ChangelistCodereviewBase): |
return 'reply' |
return 'waiting' |
+ def IsOpen(self, props=None): |
+ if not props: |
+ props = self.GetIssueProperties() |
+ return not props.get('closed') |
+ |
+ def GetCQState(self, props=None): |
+ if not props: |
+ props = self.GetIssueProperties() |
+ if props.get('commit') and not props.get('cq_dry_run'): |
+ return _CQState.COMMIT |
+ if props.get('cq_dry_run'): |
+ return _CQState.DRY_RUN |
+ return _CQState.NONE |
+ |
def UpdateDescriptionRemote(self, description): |
return self.RpcServer().update_description( |
self.GetIssue(), self.description) |
@@ -2191,16 +2219,11 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase): |
except httplib.HTTPException: |
return 'error' |
- if data['status'] in ('ABANDONED', 'MERGED'): |
+ if not self.IsOpen(data=data): |
return 'closed' |
- cq_label = data['labels'].get('Commit-Queue', {}) |
- if cq_label: |
- # Vote value is a stringified integer, which we expect from 0 to 2. |
- vote_value = cq_label.get('value', '0') |
- vote_text = cq_label.get('values', {}).get(vote_value, '') |
- if vote_text.lower() == 'commit': |
- return 'commit' |
+ if self.GetCQState(data=data) == _CQState.COMMIT: |
+ return 'commit' |
lgtm_label = data['labels'].get('Code-Review', {}) |
if lgtm_label: |
@@ -2222,6 +2245,25 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase): |
return 'waiting' |
+ def IsOpen(self, data=None): |
+ if not data: |
+ data = self._GetChangeDetail(['DETAILED_LABELS', 'CURRENT_REVISION']) |
+ return data['status'] not in ('ABANDONED', 'MERGED') |
+ |
+ def GetCQState(self, data=None): |
+ if not data: |
+ data = self._GetChangeDetail(['DETAILED_LABELS', 'CURRENT_REVISION']) |
+ cq_label = data['labels'].get('Commit-Queue', {}) |
+ if cq_label: |
+ # Vote value is a stringified integer, which we expect from 0 to 2. |
+ vote_value = cq_label.get('value', '0') |
+ vote_text = cq_label.get('values', {}).get(vote_value, '') |
+ if vote_text.lower() == 'commit': |
+ return _CQState.COMMIT |
+ if vote_test.lower() == 'dry run': |
+ return _CQState.DRY_RUN |
+ return _CQState.NONE |
+ |
def GetMostRecentPatchset(self): |
data = self._GetChangeDetail(['CURRENT_REVISION']) |
return data['revisions'][data['current_revision']]['_number'] |
@@ -5059,6 +5101,34 @@ def CMDlol(parser, args): |
return 0 |
+def CMDplumbing(parser, args): |
+ """Returns info about the CL in machine-readable form.""" |
+ parser.add_option('--json', help='Path to output JSON file') |
+ |
+ auth.add_auth_options(parser) |
+ |
+ _add_codereview_select_options(parser) |
+ options, args = parser.parse_args(args) |
+ _process_codereview_select_options(parser, options) |
+ |
+ auth_config = auth.extract_auth_config_from_options(options) |
+ |
+ cl = Changelist(auth_config=auth_config, codereview=options.forced_codereview) |
+ |
+ result = { |
+ 'open': cl.IsOpen(), |
+ 'commit_queue': cl.GetCQState(), |
+ } |
+ |
+ if options.json: |
+ with open(options.json, 'w') as f: |
+ json.dump(result, f) |
+ else: |
+ print(json.dumps(result, sort_keys=True, indent=4)) |
+ |
+ return 0 |
+ |
+ |
class OptionParser(optparse.OptionParser): |
"""Creates the option parse and add --verbose support.""" |
def __init__(self, *args, **kwargs): |