Browse Source

add a local git-cache

Christian Mönch 2 years ago
parent
commit
563e47f46c

+ 29 - 1
dataladmetadatamodel/mapper/gitmapper/gitbackend/subprocess.py

@@ -74,7 +74,18 @@ def git_load_json(repo_dir: str, object_reference: str) -> Union[Dict, List]:
     return json.loads(git_load_str(repo_dir, object_reference))
 
 
-def git_read_tree_node(repo_dir,
+def git_init(repo_dir: str) -> None:
+    cmd_line = ["git", "init", repo_dir]
+    checked_execute(cmd_line)
+
+
+def git_object_exists(repo_dir: str,
+                      object_reference) -> bool:
+    cmd_line = git_command_line(repo_dir, "cat-file", ["-e", object_reference])
+    return execute(cmd_line).returncode == 0
+
+
+def git_read_tree_node(repo_dir: str,
                        object_reference) -> List[str]:
     cmd_line = git_command_line(repo_dir, "cat-file", ["-p", object_reference])
     return checked_execute(cmd_line)[0]
@@ -131,3 +142,20 @@ def git_update_ref(repo_dir: str, ref_name: str, location: str) -> None:
         "update-ref",
         [ref_name, location])
     checked_execute(cmd_line)
+
+
+def git_fetch_reference(repo_dir: str,
+                        remote_repo: str,
+                        remote_reference: str,
+                        local_reference: str):
+    cmd_line = git_command_line(
+        repo_dir,
+        "fetch",
+        [
+            remote_repo,
+            "--no-tags",
+            "--no-recurse-submodules",
+            f"{remote_reference}:{local_reference}"
+        ]
+    )
+    checked_execute(cmd_line)

+ 37 - 0
dataladmetadatamodel/mapper/gitmapper/localcache.py

@@ -0,0 +1,37 @@
+from pathlib import Path
+
+import appdirs
+
+from .gitbackend.subprocess import (
+    git_fetch_reference,
+    git_init,
+    git_object_exists,
+)
+
+
+cache_repository_name = (
+    Path(appdirs.user_cache_dir("datalad-metalad"))
+    / "local-git-cache"
+)
+
+is_initialized = False
+
+
+def ensure_cache_is_initialized():
+    global is_initialized
+
+    if is_initialized is False:
+        git_init(str(cache_repository_name))
+        is_initialized = True
+
+
+def cache_object(remote_repo: str, object_id: str):
+    ensure_cache_is_initialized()
+
+    cache_repo = str(cache_repository_name)
+    if not git_object_exists(cache_repo, object_id):
+        git_fetch_reference(
+            cache_repo,
+            remote_repo,
+            object_id,
+            object_id)

+ 0 - 41
dataladmetadatamodel/mapper/memorymapper.py

@@ -1,41 +0,0 @@
-from collections import defaultdict
-from typing import Any
-
-from dataladmetadatamodel.mapper.mapper import Mapper
-from dataladmetadatamodel.mapper.reference import Reference
-
-
-class MemoryMapper(Mapper):
-    instance = None
-
-    def __init__(self):
-        super().__init__("memory")
-        self.objects = dict()
-        self.index = 1000
-
-    def __call__(self, *args, **kwargs):
-        return self
-
-    def map_impl(self, reference: Reference) -> Any:
-        index = int(reference.location)
-        print(f"mapper: loading reference {reference}: {self.objects[index]}")
-        return self.objects[index]
-
-    def unmap_impl(self, obj) -> Reference:
-        location = str(self.index)
-        print(f"mapper: saving object {obj}: {location}")
-        self.objects[self.index] = obj
-        self.index += 1
-        return Reference("memory", "memory", type(obj).__name__, location)
-
-    @classmethod
-    def get_instance(cls):
-        if MemoryMapper.instance is None:
-            MemoryMapper.instance = MemoryMapper()
-        return MemoryMapper.instance
-
-
-MEMORY_MAPPER_FAMILY = defaultdict(MemoryMapper)
-
-
-MEMORY_MAPPER_LOCATIONS = ("0", "1")

+ 1 - 0
requirements.txt

@@ -1,3 +1,4 @@
+appdirs
 nose
 click
 dataclasses