ac3c440a29a4

API work.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sun, 04 Oct 2009 18:33:20 -0400
parents f090d7d568a4
children cdd63ba4a8f8
branches/tags (none)
files review/api.py

Changes

--- a/review/api.py	Sun Oct 04 17:52:11 2009 -0400
+++ b/review/api.py	Sun Oct 04 18:33:20 2009 -0400
@@ -4,10 +4,21 @@
 '''
 
 import os
+from datetime import datetime
 from mercurial import cmdutil, hg
 from mercurial.node import hex
+from mercurial.util import sha1
 
 
+COMMENT_FILE_TEMPLATE = '''\
+author:%s
+datetime:%s
+node:%s
+filename:%s
+lines:%s
+
+%s'''
+
 class PreexistingDatastore(Exception):
     """Raised when trying to initialize a datastore when one seems to exist."""
     def __init__(self, committed):
@@ -38,7 +49,14 @@
     return lambda fn: fn.startswith(start)
 
 def _parse_comment_data(data):
-    return None
+    meta, _, message = data.partition('\n\n')
+    
+    data = {}
+    for m in meta.split('\n'):
+        label, _, val = m.partition(':')
+        data[label] = val
+    data['message'] = message
+    return data
 
 def _parse_signoffdata(data):
     return None
@@ -81,9 +99,12 @@
         '''Add (and commit) a signoff for the given revision.'''
         pass
     
-    def add_comment(self, rev, message):
-        '''Add (and commit) a comment for the given revision.'''
-        pass
+    def add_comment(self, message, rev='.', filename='', lines=[]):
+        '''Add (and commit) a comment for the given revision, file, and lines.'''
+        node = hex(self.target[rev].node())
+        comment = ReviewComment(self.ui.username(), datetime.utcnow(), node,
+            filename, lines, message)
+        comment.commit(self.repo)
     
 
 
@@ -100,8 +121,10 @@
             commentfns = filter(_match('%s/comments' % node), relevant)
             signofffns = filter(_match('%s/signoffs' % node), relevant)
             
-            self.comments = [ _parse_comment_data(self.repo['tip'][fn].data())
-                              for fn in commentfns ]
+            self.comments = [ 
+                ReviewComment(**_parse_comment_data(self.repo['tip'][fn].data()))
+                              for fn in commentfns
+            ]
             self.signoffs = [ _parse_signoff_data(self.repo['tip'][fn].data())
                               for fn in signofffns ]
             
@@ -121,3 +144,39 @@
                   'addremove': True, })
     
 
+class ReviewComment(object):
+    '''A single review comment.'''
+    
+    def __init__(self, author, datetime, node, filename, lines, message, **extra):
+        self.author = author
+        self.datetime = datetime
+        self.node = node
+        self.filename = filename
+        self.lines = lines
+        self.message = message
+    
+    def render_data(self):
+        datetime = str(self.datetime)
+        lines = ','.join(self.lines)
+        return COMMENT_FILE_TEMPLATE % ( self.author, datetime,
+            self.node, self.filename, lines, self.message )
+    
+    def commit(self, repo):
+        '''Write and commit this comment to the given repo.'''
+        
+        path = os.path.join(repo.root, self.node, 'comments')
+        os.mkdir(path)
+        
+        data = self.render_data()
+        filename = sha1(data)
+        commentpath = os.path.join(path, filename)
+        
+        with open(commentpath, 'w') as commentfile:
+            commentfile.write(data)
+        
+        cmdutil.commit(ui, self.repo, _commitfunc,
+            [commentpath],
+            { 'message': 'Add a comment on changeset %s' % self.node,
+              'addremove': True, })
+    
+