@ -1713,13 +1713,13 @@ class Changelist(object):
def AddComment ( self , message ) :
return self . _codereview_impl . AddComment ( message )
def GetCommentsSummary ( self ):
def GetCommentsSummary ( self , readable = True ):
""" Returns list of _CommentSummary for each comment.
Note: comments per file or per line are not included ,
only top - level comments are returned .
args:
readable: determines whether the output is designed for a human or a machine
"""
return self . _codereview_impl . GetCommentsSummary ( )
return self . _codereview_impl . GetCommentsSummary ( readable )
def CloseIssue ( self ) :
return self . _codereview_impl . CloseIssue ( )
@ -1820,7 +1820,7 @@ class _ChangelistCodereviewBase(object):
""" Posts a comment to the codereview site. """
raise NotImplementedError ( )
def GetCommentsSummary ( self ):
def GetCommentsSummary ( self , readable = True ):
raise NotImplementedError ( )
def CloseIssue ( self ) :
@ -1996,7 +1996,7 @@ class _RietveldChangelistImpl(_ChangelistCodereviewBase):
def AddComment ( self , message ) :
return self . RpcServer ( ) . add_comment ( self . GetIssue ( ) , message )
def GetCommentsSummary ( self ):
def GetCommentsSummary ( self , _readable = True ):
summary = [ ]
for message in self . GetIssueProperties ( ) . get ( ' messages ' , [ ] ) :
date = datetime . datetime . strptime ( message [ ' date ' ] , ' % Y- % m- %d % H: % M: % S. %f ' )
@ -2581,18 +2581,67 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase):
gerrit_util . SetReview ( self . _GetGerritHost ( ) , self . GetIssue ( ) ,
msg = message )
def GetCommentsSummary ( self ):
def GetCommentsSummary ( self , readable = True ):
# DETAILED_ACCOUNTS is to get emails in accounts.
data = self . _GetChangeDetail ( options = [ ' MESSAGES ' , ' DETAILED_ACCOUNTS ' ] )
messages = self . _GetChangeDetail (
options = [ ' MESSAGES ' , ' DETAILED_ACCOUNTS ' ] ) . get ( ' messages ' , [ ] )
file_comments = gerrit_util . GetChangeComments (
self . _GetGerritHost ( ) , self . GetIssue ( ) )
# Build dictionary of file comments for easy access and sorting later.
# {author+date: {path: {patchset: {line: url+message}}}}
comments = collections . defaultdict (
lambda : collections . defaultdict ( lambda : collections . defaultdict ( dict ) ) )
for path , line_comments in file_comments . iteritems ( ) :
for comment in line_comments :
if comment . get ( ' tag ' , ' ' ) . startswith ( ' autogenerated ' ) :
continue
key = ( comment [ ' author ' ] [ ' email ' ] , comment [ ' updated ' ] )
if comment . get ( ' side ' , ' REVISION ' ) == ' PARENT ' :
patchset = ' Base '
else :
patchset = ' PS %d ' % comment [ ' patch_set ' ]
line = comment . get ( ' line ' , 0 )
url = ( ' https:// %s /c/ %s / %s / %s # %s %s ' %
( self . _GetGerritHost ( ) , self . GetIssue ( ) , comment [ ' patch_set ' ] , path ,
' b ' if comment . get ( ' side ' ) == ' PARENT ' else ' ' ,
str ( line ) if line else ' ' ) )
comments [ key ] [ path ] [ patchset ] [ line ] = ( url , comment [ ' message ' ] )
summary = [ ]
for msg in data . get ( ' messages ' , [ ] ) :
for msg in messages :
# Don't bother showing autogenerated messages.
if msg . get ( ' tag ' ) and msg . get ( ' tag ' ) . startswith ( ' autogenerated ' ) :
continue
# Gerrit spits out nanoseconds.
assert len ( msg [ ' date ' ] . split ( ' . ' ) [ - 1 ] ) == 9
date = datetime . datetime . strptime ( msg [ ' date ' ] [ : - 3 ] ,
' % Y- % m- %d % H: % M: % S. %f ' )
message = msg [ ' message ' ]
key = ( msg [ ' author ' ] [ ' email ' ] , msg [ ' date ' ] )
if key in comments :
message + = ' \n '
for path , patchsets in sorted ( comments . get ( key , { } ) . items ( ) ) :
if readable :
message + = ' \n %s ' % path
for patchset , lines in sorted ( patchsets . items ( ) ) :
for line , ( url , content ) in sorted ( lines . items ( ) ) :
if line :
line_str = ' Line %d ' % line
path_str = ' %s : %d : ' % ( path , line )
else :
line_str = ' File comment '
path_str = ' %s :0: ' % path
if readable :
message + = ' \n %s , %s : %s ' % ( patchset , line_str , url )
message + = ' \n %s \n ' % content
else :
message + = ' \n %s ' % path_str
message + = ' \n %s \n ' % content
summary . append ( _CommentSummary (
date = date ,
message = msg [ ' message ' ] ,
message = m essage,
sender = msg [ ' author ' ] [ ' email ' ] ,
# These could be inferred from the text messages and correlated with
# Code-Review label maximum, however this is not reliable.
@ -4398,6 +4447,10 @@ def CMDcomments(parser, args):
parser . add_option ( ' -i ' , ' --issue ' , dest = ' issue ' ,
help = ' review issue id (defaults to current issue). '
' If given, requires --rietveld or --gerrit ' )
parser . add_option ( ' -m ' , ' --machine-readable ' , dest = ' readable ' ,
action = ' store_false ' , default = True ,
help = ' output comments in a format compatible with '
' editor parsing ' )
parser . add_option ( ' -j ' , ' --json-file ' ,
help = ' File to write JSON summary to ' )
auth . add_auth_options ( parser )
@ -4423,7 +4476,8 @@ def CMDcomments(parser, args):
cl . AddComment ( options . comment )
return 0
summary = sorted ( cl . GetCommentsSummary ( ) , key = lambda c : c . date )
summary = sorted ( cl . GetCommentsSummary ( readable = options . readable ) ,
key = lambda c : c . date )
for comment in summary :
if comment . disapproval :
color = Fore . RED