|
|
@ -1973,88 +1973,25 @@ class _RietveldChangelistImpl(_ChangelistCodereviewBase):
|
|
|
|
raise NotImplementedError()
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
def GetIssueOwner(self):
|
|
|
|
def GetIssueOwner(self):
|
|
|
|
return (self.GetIssueProperties() or {}).get('owner_email')
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
def GetReviewers(self):
|
|
|
|
def GetReviewers(self):
|
|
|
|
return (self.GetIssueProperties() or {}).get('reviewers')
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
def AddComment(self, message, publish=None):
|
|
|
|
def AddComment(self, message, publish=None):
|
|
|
|
return self.RpcServer().add_comment(self.GetIssue(), message)
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
def GetCommentsSummary(self, _readable=True):
|
|
|
|
def GetCommentsSummary(self, readable=True):
|
|
|
|
summary = []
|
|
|
|
raise NotImplementedError()
|
|
|
|
for message in self.GetIssueProperties().get('messages', []):
|
|
|
|
|
|
|
|
date = datetime.datetime.strptime(message['date'], '%Y-%m-%d %H:%M:%S.%f')
|
|
|
|
|
|
|
|
summary.append(_CommentSummary(
|
|
|
|
|
|
|
|
date=date,
|
|
|
|
|
|
|
|
disapproval=bool(message['disapproval']),
|
|
|
|
|
|
|
|
approval=bool(message['approval']),
|
|
|
|
|
|
|
|
sender=message['sender'],
|
|
|
|
|
|
|
|
message=message['text'],
|
|
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
return summary
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def GetStatus(self):
|
|
|
|
def GetStatus(self):
|
|
|
|
"""Applies a rough heuristic to give a simple summary of an issue's review
|
|
|
|
raise NotImplementedError()
|
|
|
|
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
|
|
|
|
|
|
|
|
* 'not lgtm' - Code-Review label has been set negatively
|
|
|
|
|
|
|
|
* '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') and not props.get('cq_dry_run', False):
|
|
|
|
|
|
|
|
# Issue is in the commit queue.
|
|
|
|
|
|
|
|
return 'commit'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
messages = props.get('messages') or []
|
|
|
|
|
|
|
|
if not messages:
|
|
|
|
|
|
|
|
# No message was sent.
|
|
|
|
|
|
|
|
return 'unsent'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if get_approving_reviewers(props):
|
|
|
|
|
|
|
|
return 'lgtm'
|
|
|
|
|
|
|
|
elif get_approving_reviewers(props, disapproval=True):
|
|
|
|
|
|
|
|
return 'not lgtm'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Skip CQ messages that don't require owner's action.
|
|
|
|
|
|
|
|
while messages and messages[-1]['sender'] == COMMIT_BOT_EMAIL:
|
|
|
|
|
|
|
|
if 'Dry run:' in messages[-1]['text']:
|
|
|
|
|
|
|
|
messages.pop()
|
|
|
|
|
|
|
|
elif 'The CQ bit was unchecked' in messages[-1]['text']:
|
|
|
|
|
|
|
|
# This message always follows prior messages from CQ,
|
|
|
|
|
|
|
|
# so skip this too.
|
|
|
|
|
|
|
|
messages.pop()
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
# This is probably a CQ messages warranting user attention.
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if messages[-1]['sender'] != props.get('owner_email'):
|
|
|
|
|
|
|
|
# Non-LGTM reply from non-owner and not CQ bot.
|
|
|
|
|
|
|
|
return 'reply'
|
|
|
|
|
|
|
|
return 'waiting'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def UpdateDescriptionRemote(self, description, force=False):
|
|
|
|
def UpdateDescriptionRemote(self, description, force=False):
|
|
|
|
self.RpcServer().update_description(self.GetIssue(), description)
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
def CloseIssue(self):
|
|
|
|
def CloseIssue(self):
|
|
|
|
return self.RpcServer().close_issue(self.GetIssue())
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
def SetFlag(self, flag, value):
|
|
|
|
def SetFlag(self, flag, value):
|
|
|
|
return self.SetFlags({flag: value})
|
|
|
|
return self.SetFlags({flag: value})
|
|
|
|