--- 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, })
+
+