Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions src/semble/cache.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import hashlib
import json
import logging
import os
import shutil
import sys
Expand All @@ -13,6 +14,8 @@
from semble.types import ContentType
from semble.utils import is_git_url, resolve_model_name

logger = logging.getLogger(__name__)

if TYPE_CHECKING:
from semble.index import SembleIndex

Expand Down Expand Up @@ -48,11 +51,24 @@ def _linux_cache_dir(name: str) -> Path:
return base / name


def _get_valid_user_cache_dir() -> Path | None:
"""Gets the user cache dir if it is set and is a valid path."""
user_cache_location = os.getenv("SEMBLE_CACHE_LOCATION")
if user_cache_location is None:
return None
user_cache_dir = Path(user_cache_location)
if not user_cache_dir.is_absolute():
logger.warning("SEMBLE_CACHE_LOCATION is not an absolute path: %s", user_cache_location)
return None

return user_cache_dir


def resolve_cache_folder() -> Path:
"""Resolves a cache folder, respects SEMBLE_CACHE_LOCATION (highest precedence), XDG_CACHE_HOME."""
name = "semble"
if semble_cache_location := os.getenv("SEMBLE_CACHE_LOCATION"):
cache_dir = Path(semble_cache_location)
if user_cache_dir := _get_valid_user_cache_dir():
cache_dir = user_cache_dir
elif sys.platform == "win32":
cache_dir = _windows_cache_dir(name)
elif sys.platform == "darwin":
Expand Down
9 changes: 9 additions & 0 deletions tests/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import pytest

from semble.cache import (
_get_valid_user_cache_dir,
_linux_cache_dir,
_windows_cache_dir,
clear_cache,
Expand Down Expand Up @@ -93,6 +94,14 @@ def test_resolve_cache_folder(platform: str, mock_target: str, expected: Path) -
assert result == expected


def test_get_valid_user_cache_dir_relative_path() -> None:
"""_get_valid_user_cache_dir returns None when SEMBLE_CACHE_LOCATION is a relative path."""
with patch.dict("os.environ", {"SEMBLE_CACHE_LOCATION": "relative/path"}):
with patch("semble.cache.logger") as mock_logger:
assert _get_valid_user_cache_dir() is None
mock_logger.warning.assert_called_once()


def test_resolve_cache_folder_semble_cache_location(tmp_path: Path) -> None:
"""SEMBLE_CACHE_LOCATION takes precedence over all platform-specific helpers."""
custom = tmp_path / "custom_cache"
Expand Down
Loading