Add a MemoryRepo that stores everything in memory.
authorDave Borowitz <dborowitz@google.com>
Thu, 13 May 2010 00:47:46 +0000 (17:47 -0700)
committerDave Borowitz <dborowitz@google.com>
Tue, 1 Jun 2010 22:33:55 +0000 (15:33 -0700)
This just delegates to a MemoryObjectStore and DictRefsContainer, with a
dict of contents for named files.

As with MemoryObjectStore and DictRefsContainer, this will be useful
primarily for tests.

Change-Id: Ide345a397a0dcde990531bbc4854569ea3274b17

NEWS
dulwich/repo.py
dulwich/tests/test_repository.py

diff --git a/NEWS b/NEWS
index 4681e9f..716af74 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,8 @@
 
   * Add tests for sorted_tree_items and C implementation. (Dave Borowitz)
 
+  * Add a MemoryRepo that stores everything in memory. (Dave Borowitz)
+
  CLEANUP
 
   * Clean up file headers. (Dave Borowitz)
index 322d776..ffa0588 100644 (file)
@@ -21,7 +21,7 @@
 
 """Repository access."""
 
-
+from cStringIO import StringIO
 import errno
 import os
 
@@ -42,6 +42,7 @@ from dulwich.file import (
     )
 from dulwich.object_store import (
     DiskObjectStore,
+    MemoryObjectStore,
     )
 from dulwich.objects import (
     Blob,
@@ -1191,3 +1192,53 @@ class Repo(BaseRepo):
         return ret
 
     create = init_bare
+
+
+class MemoryRepo(BaseRepo):
+    """Repo that stores refs, objects, and named files in memory.
+
+    MemoryRepos are always bare: they have no working tree and no index, since
+    those have a stronger dependency on the filesystem.
+    """
+
+    def __init__(self):
+        BaseRepo.__init__(self, MemoryObjectStore(), DictRefsContainer({}))
+        self._named_files = {}
+        self.bare = True
+
+    def _put_named_file(self, path, contents):
+        """Write a file to the control dir with the given name and contents.
+
+        :param path: The path to the file, relative to the control dir.
+        :contents: A string to write to the file.
+        """
+        self._named_files[path] = contents
+
+    def get_named_file(self, path):
+        """Get a file from the control dir with a specific name.
+
+        Although the filename should be interpreted as a filename relative to
+        the control dir in a disk-baked Repo, the object returned need not be
+        pointing to a file in that location.
+
+        :param path: The path to the file, relative to the control dir.
+        :return: An open file object, or None if the file does not exist.
+        """
+        contents = self._named_files.get(path, None)
+        if contents is None:
+            return None
+        return StringIO(contents)
+
+    def open_index(self):
+        """Fail to open index for this repo, since it is bare."""
+        raise NoIndexPresent()
+
+    @classmethod
+    def init_bare(cls, objects, refs):
+        ret = cls()
+        for obj in objects:
+            ret.object_store.add_object(obj)
+        for refname, sha in refs.iteritems():
+            ret.refs[refname] = sha
+        ret._init_files()
+        return ret
index 423d3b1..570615c 100644 (file)
@@ -35,6 +35,7 @@ from dulwich.repo import (
     check_ref_format,
     DictRefsContainer,
     Repo,
+    MemoryRepo,
     read_packed_refs,
     read_packed_refs_with_peeled,
     write_packed_refs,
@@ -75,6 +76,10 @@ class CreateRepositoryTests(unittest.TestCase):
         finally:
             shutil.rmtree(tmp_dir)
 
+    def test_create_memory(self):
+        repo = MemoryRepo.init_bare([], {})
+        self._check_repo_contents(repo)
+
 
 class RepositoryTests(unittest.TestCase):