Skip to content

Commit 9f1db23

Browse files
groksrcclaude[bot]
andauthored
fix: respect BASIC_MEMORY_HOME environment variable in Docker containers (#174)
Signed-off-by: Drew Cain <groksrc@gmail.com> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
1 parent db5ef7d commit 9f1db23

2 files changed

Lines changed: 87 additions & 2 deletions

File tree

src/basic_memory/config.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ class BasicMemoryConfig(BaseSettings):
4545
env: Environment = Field(default="dev", description="Environment name")
4646

4747
projects: Dict[str, str] = Field(
48-
default_factory=lambda: {"main": str(Path.home() / "basic-memory")},
48+
default_factory=lambda: {
49+
"main": str(Path(os.getenv("BASIC_MEMORY_HOME", Path.home() / "basic-memory")))
50+
},
4951
description="Mapping of project names to their filesystem paths",
5052
)
5153
default_project: str = Field(
@@ -92,7 +94,7 @@ def model_post_init(self, __context: Any) -> None:
9294
"""Ensure configuration is valid after initialization."""
9395
# Ensure main project exists
9496
if "main" not in self.projects: # pragma: no cover
95-
self.projects["main"] = str(Path.home() / "basic-memory")
97+
self.projects["main"] = str(Path(os.getenv("BASIC_MEMORY_HOME", Path.home() / "basic-memory")))
9698

9799
# Ensure default project is valid
98100
if self.default_project not in self.projects: # pragma: no cover

tests/test_config.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"""Test configuration management."""
2+
3+
import os
4+
from pathlib import Path
5+
6+
import pytest
7+
8+
from basic_memory.config import BasicMemoryConfig
9+
10+
11+
class TestBasicMemoryConfig:
12+
"""Test BasicMemoryConfig behavior with BASIC_MEMORY_HOME environment variable."""
13+
14+
def test_default_behavior_without_basic_memory_home(self, config_home, monkeypatch):
15+
"""Test that config uses default path when BASIC_MEMORY_HOME is not set."""
16+
# Ensure BASIC_MEMORY_HOME is not set
17+
monkeypatch.delenv("BASIC_MEMORY_HOME", raising=False)
18+
19+
config = BasicMemoryConfig()
20+
21+
# Should use the default path (home/basic-memory)
22+
expected_path = str(config_home / "basic-memory")
23+
assert config.projects["main"] == expected_path
24+
25+
def test_respects_basic_memory_home_environment_variable(self, config_home, monkeypatch):
26+
"""Test that config respects BASIC_MEMORY_HOME environment variable."""
27+
custom_path = str(config_home / "app" / "data")
28+
monkeypatch.setenv("BASIC_MEMORY_HOME", custom_path)
29+
30+
config = BasicMemoryConfig()
31+
32+
# Should use the custom path from environment variable
33+
assert config.projects["main"] == custom_path
34+
35+
def test_model_post_init_respects_basic_memory_home(self, config_home, monkeypatch):
36+
"""Test that model_post_init creates main project with BASIC_MEMORY_HOME when missing."""
37+
custom_path = str(config_home / "custom" / "memory" / "path")
38+
monkeypatch.setenv("BASIC_MEMORY_HOME", custom_path)
39+
40+
# Create config without main project
41+
other_path = str(config_home / "some" / "path")
42+
config = BasicMemoryConfig(projects={"other": other_path})
43+
44+
# model_post_init should have added main project with BASIC_MEMORY_HOME
45+
assert "main" in config.projects
46+
assert config.projects["main"] == custom_path
47+
48+
def test_model_post_init_fallback_without_basic_memory_home(self, config_home, monkeypatch):
49+
"""Test that model_post_init falls back to default when BASIC_MEMORY_HOME is not set."""
50+
# Ensure BASIC_MEMORY_HOME is not set
51+
monkeypatch.delenv("BASIC_MEMORY_HOME", raising=False)
52+
53+
# Create config without main project
54+
other_path = str(config_home / "some" / "path")
55+
config = BasicMemoryConfig(projects={"other": other_path})
56+
57+
# model_post_init should have added main project with default path
58+
expected_path = str(config_home / "basic-memory")
59+
assert "main" in config.projects
60+
assert config.projects["main"] == expected_path
61+
62+
def test_basic_memory_home_with_relative_path(self, config_home, monkeypatch):
63+
"""Test that BASIC_MEMORY_HOME works with relative paths."""
64+
relative_path = "relative/memory/path"
65+
monkeypatch.setenv("BASIC_MEMORY_HOME", relative_path)
66+
67+
config = BasicMemoryConfig()
68+
69+
# Should use the exact value from environment variable
70+
assert config.projects["main"] == relative_path
71+
72+
def test_basic_memory_home_overrides_existing_main_project(self, config_home, monkeypatch):
73+
"""Test that BASIC_MEMORY_HOME is not used when a map is passed in the constructor."""
74+
custom_path = str(config_home / "override" / "memory" / "path")
75+
monkeypatch.setenv("BASIC_MEMORY_HOME", custom_path)
76+
77+
# Try to create config with a different main project path
78+
original_path = str(config_home / "original" / "path")
79+
config = BasicMemoryConfig(projects={"main": original_path})
80+
81+
# The default_factory should override with BASIC_MEMORY_HOME value
82+
# Note: This tests the current behavior where default_factory takes precedence
83+
assert config.projects["main"] == original_path

0 commit comments

Comments
 (0)