537000a18d86

api: add support for deleting items
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 19 Jun 2010 02:03:29 -0400
parents d2a44912c2f7
children e29d33ec47b1
branches/tags (none)
files review/api.py review/messages.py

Changes

--- 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
+"""