--- a/review/api.py Sat Jun 19 01:55:46 2010 -0400
+++ b/review/api.py Sat Jun 19 02:03:29 2010 -0400
@@ -64,10 +64,6 @@
"""Raised when trying to signoff twice without forcing."""
pass
-class CannotDeleteObject(Exception):
- """Raised when trying to delete an object that does not support deletion."""
- pass
-
class FileNotInChangeset(Exception):
"""Raised when trying to add a comment on a file not in the changeset."""
def __init__(self, filename):
@@ -75,6 +71,15 @@
self.filename = filename
+class AmbiguousIdentifier(Exception):
+ """Raised when trying to specify an item with an identifier which matches more than one item."""
+ pass
+
+class UnknownIdentifier(Exception):
+ """Raised when trying to specify an item with an identifier which does not match any items."""
+ pass
+
+
def _split_path_dammit(p):
"""Take a file path (from the current platform) and split it. Really.
@@ -158,6 +163,8 @@
else:
return bare_datetime - offset
+def _flatten_filter(i):
+ return filter(None, reduce(operator.add, i, []))
def sanitize_path(p, repo=None):
"""Sanitize a (platform-specific) path.
@@ -256,6 +263,42 @@
node = hex(self.target[str(rev)].node())
return ReviewChangeset(self.ui, self.repo, self.target, node)
+
+ def reviewed_changesets(self):
+ """Return a list of all the ReviewChangesets in the data store."""
+ hashes = []
+ for fname in os.listdir(self.repo.root):
+ if os.path.isdir(os.path.join(self.repo.root, fname)):
+ try:
+ self.target[fname]
+ hashes.append(self[fname])
+ except error.RepoLookupError:
+ pass
+ return hashes
+
+
+ def get_items(self, identifier):
+ """Return the comments and signoffs which match the given identifier.
+
+ WARNING: This is going to be slow. Send patches.
+
+ """
+ rcsets = self.reviewed_changesets()
+ comments = _flatten_filter(rcset.comments for rcset in rcsets)
+ signoffs = _flatten_filter(rcset.signoffs for rcset in rcsets)
+ return [i for i in comments + signoffs if i.identifier.startswith(identifier)]
+
+ def remove_item(self, identifier):
+ """Remove a comment or signoff from this changeset."""
+ items = self.get_items(identifier)
+ if len(items) == 0:
+ raise UnknownIdentifier
+ elif len(items) > 1:
+ raise AmbiguousIdentifier
+ else:
+ items[0]._delete(self.ui, self.repo)
+
+
class ReviewChangeset(object):
"""The review data about one changeset in the target repository.
@@ -603,6 +646,7 @@
lambda c: filename and c.lines, self.comments
)
+
class _ReviewObject(object):
"""A base object for some kind of review data (a signoff or comment)."""
def __init__(self, container, commit_message, delete_message=None):
@@ -630,9 +674,6 @@
def _delete(self, ui, repo):
"""Delete and commit this object in the given repo."""
- if not self.delete_message:
- raise CannotDeleteObject
-
data = self._render_data()
filename = util.sha1(data).hexdigest()
objectpath = os.path.join(repo.root, self.node, self.container, filename)
@@ -692,6 +733,7 @@
"""
super(ReviewComment, self).__init__(
container='comments', commit_message=messages.COMMIT_COMMENT,
+ delete_message=messages.DELETE_COMMENT
)
self.author = author
self.hgdate = hgdate
--- a/review/messages.py Sat Jun 19 01:55:46 2010 -0400
+++ b/review/messages.py Sat Jun 19 02:03:29 2010 -0400
@@ -136,8 +136,11 @@
"""
COMMIT_COMMENT = """Add a comment on changeset %s"""
+DELETE_COMMENT = """Remove comment off from changeset %s"""
+
COMMIT_SIGNOFF = """Sign off on changeset %s"""
DELETE_SIGNOFF = """Remove sign off on changeset %s"""
+
FETCH = """Automated merge of review data."""
WEB_START = """\
@@ -159,3 +162,15 @@
CHECK_UNSEEN = """\
changeset has no comments or signoffs
"""
+
+DELETE_AMBIGUOUS_ID = """\
+the identifier '%s' matches more than one item!
+"""
+
+DELETE_UNKNOWN_ID = """\
+unknown item '%s'!
+"""
+
+DELETE_REQUIRES_IDS = """\
+no items specified
+"""