mirror of
https://github.com/usestrix/strix.git
synced 2026-08-25 20:32:38 +02:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
857b24454d | ||
|
|
7a736da465 |
+24
-2
@@ -54,12 +54,16 @@ def apply_config_override(path: Path) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def persist_current() -> None:
|
def persist_current() -> None:
|
||||||
"""Write currently-set env vars to the active config file (0o600)."""
|
"""Merge currently-set env vars into the active config file (0o600).
|
||||||
|
|
||||||
|
Keys already on disk are preserved (including keys unknown to this
|
||||||
|
version's schema); env vars win on conflicts.
|
||||||
|
"""
|
||||||
s = load_settings()
|
s = load_settings()
|
||||||
target = _override or _DEFAULT_PATH
|
target = _override or _DEFAULT_PATH
|
||||||
target.parent.mkdir(parents=True, exist_ok=True)
|
target.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
env_block: dict[str, str] = {}
|
env_block: dict[str, Any] = _read_persisted_env(target)
|
||||||
for sub_name in s.model_fields:
|
for sub_name in s.model_fields:
|
||||||
sub_model = getattr(s, sub_name)
|
sub_model = getattr(s, sub_name)
|
||||||
if not isinstance(sub_model, BaseModel):
|
if not isinstance(sub_model, BaseModel):
|
||||||
@@ -74,6 +78,24 @@ def persist_current() -> None:
|
|||||||
write_secret_text(target, json.dumps({"env": env_block}, indent=2))
|
write_secret_text(target, json.dumps({"env": env_block}, indent=2))
|
||||||
|
|
||||||
|
|
||||||
|
def _read_persisted_env(path: Path) -> dict[str, Any]:
|
||||||
|
"""Read the ``{"env": {...}}`` block already stored at ``path``."""
|
||||||
|
if not path.exists():
|
||||||
|
return {}
|
||||||
|
try:
|
||||||
|
data = json.loads(path.read_text(encoding="utf-8"))
|
||||||
|
except (json.JSONDecodeError, OSError):
|
||||||
|
return {}
|
||||||
|
env_block = data.get("env", {}) if isinstance(data, dict) else {}
|
||||||
|
if not isinstance(env_block, dict):
|
||||||
|
return {}
|
||||||
|
return {
|
||||||
|
str(key).upper(): value
|
||||||
|
for key, value in env_block.items()
|
||||||
|
if value is not None and value != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _aliases_for(finfo: FieldInfo) -> list[str]:
|
def _aliases_for(finfo: FieldInfo) -> list[str]:
|
||||||
"""Collect every env-var name that should populate ``finfo``."""
|
"""Collect every env-var name that should populate ``finfo``."""
|
||||||
aliases: list[str] = []
|
aliases: list[str] = []
|
||||||
|
|||||||
@@ -208,6 +208,69 @@ def test_persist_current_writes_env_block(tmp_path: Path, monkeypatch: pytest.Mo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_persist_current_preserves_keys_missing_from_env(
|
||||||
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
|
monkeypatch.delenv("STRIX_LLM", raising=False)
|
||||||
|
monkeypatch.delenv("LLM_API_KEY", raising=False)
|
||||||
|
monkeypatch.setenv("OPENAI_API_KEY", "env-key")
|
||||||
|
target = tmp_path / "cli-config.json"
|
||||||
|
target.write_text(
|
||||||
|
json.dumps({"env": {"STRIX_LLM": "file-model", "STRIX_FUTURE_KEY": "keep-me"}}),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
loader.apply_config_override(target)
|
||||||
|
|
||||||
|
loader.persist_current()
|
||||||
|
|
||||||
|
assert json.loads(target.read_text(encoding="utf-8")) == {
|
||||||
|
"env": {
|
||||||
|
"STRIX_LLM": "file-model",
|
||||||
|
"STRIX_FUTURE_KEY": "keep-me",
|
||||||
|
"OPENAI_API_KEY": "env-key",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_persist_current_env_wins_over_persisted_value(
|
||||||
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
|
monkeypatch.setenv("STRIX_LLM", "env-model")
|
||||||
|
target = tmp_path / "cli-config.json"
|
||||||
|
target.write_text(json.dumps({"env": {"STRIX_LLM": "file-model"}}), encoding="utf-8")
|
||||||
|
loader.apply_config_override(target)
|
||||||
|
|
||||||
|
loader.persist_current()
|
||||||
|
|
||||||
|
assert json.loads(target.read_text(encoding="utf-8"))["env"]["STRIX_LLM"] == "env-model"
|
||||||
|
|
||||||
|
|
||||||
|
def test_persist_current_preserves_dict_valued_key(
|
||||||
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
|
monkeypatch.delenv("STRIX_LLM", raising=False)
|
||||||
|
monkeypatch.delenv("LLM_EXTRA_HEADERS", raising=False)
|
||||||
|
target = tmp_path / "cli-config.json"
|
||||||
|
target.write_text(
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"STRIX_LLM": "file-model",
|
||||||
|
"LLM_EXTRA_HEADERS": {"X-Foo": "bar"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
loader.apply_config_override(target)
|
||||||
|
|
||||||
|
loader.persist_current()
|
||||||
|
|
||||||
|
persisted_env = json.loads(target.read_text(encoding="utf-8"))["env"]
|
||||||
|
assert persisted_env["STRIX_LLM"] == "file-model"
|
||||||
|
assert persisted_env["LLM_EXTRA_HEADERS"] == {"X-Foo": "bar"}
|
||||||
|
|
||||||
|
|
||||||
def test_persist_current_sets_0600_mode(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
def test_persist_current_sets_0600_mode(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
monkeypatch.setenv("STRIX_LLM", "persisted-model")
|
monkeypatch.setenv("STRIX_LLM", "persisted-model")
|
||||||
target = tmp_path / "cli-config.json"
|
target = tmp_path / "cli-config.json"
|
||||||
|
|||||||
Reference in New Issue
Block a user