localcache.py 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. """
  2. Different remote repositories have to be cached in different
  3. local repositories to avoid conflicts in reference name space
  4. """
  5. import hashlib
  6. from pathlib import Path
  7. import appdirs
  8. from .gitbackend.subprocess import (
  9. git_fetch_object,
  10. git_fetch_reference,
  11. git_init,
  12. git_object_exists_locally,
  13. )
  14. cache_repository_base = (
  15. Path(appdirs.user_cache_dir("datalad-metalad"))
  16. / "local-git-cache"
  17. )
  18. def get_name_hash(name: str) -> str:
  19. return hashlib.sha256(name.encode()).hexdigest()
  20. def get_repo_cache_path(remote_repo: str) -> Path:
  21. return cache_repository_base / get_name_hash(remote_repo)
  22. def ensure_cache_exists(remote_repo: str):
  23. cache_path = get_repo_cache_path(remote_repo)
  24. if not cache_path.exists():
  25. git_init(str(cache_path))
  26. def cache_object(remote_repo: str, object_id: str):
  27. ensure_cache_exists(remote_repo)
  28. cache_repo = str(get_repo_cache_path(remote_repo))
  29. if object_id.startswith("refs"):
  30. git_fetch_reference(
  31. cache_repo,
  32. remote_repo,
  33. object_id,
  34. object_id)
  35. elif not git_object_exists_locally(cache_repo, object_id):
  36. git_fetch_object(
  37. cache_repo,
  38. remote_repo,
  39. object_id)
  40. def get_cache_realm(remote_repo: str) -> Path:
  41. return get_repo_cache_path(remote_repo)