fix(config): preserve permissions during atomic save
This commit is contained in:
@@ -5,6 +5,7 @@ import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import stat
|
||||
import time
|
||||
import uuid
|
||||
from contextlib import suppress
|
||||
@@ -454,8 +455,13 @@ def _cleanup_tool_result_buckets(root: Path, current_bucket: Path) -> None:
|
||||
|
||||
def _write_text_atomic(path: Path, content: str) -> None:
|
||||
tmp = path.with_name(f".{path.name}.{uuid.uuid4().hex}.tmp")
|
||||
existing_mode: int | None = None
|
||||
with suppress(OSError):
|
||||
existing_mode = stat.S_IMODE(path.stat().st_mode)
|
||||
try:
|
||||
with open(tmp, "w", encoding="utf-8") as f:
|
||||
if existing_mode is not None:
|
||||
os.chmod(tmp, existing_mode)
|
||||
f.write(content)
|
||||
f.flush()
|
||||
os.fsync(f.fileno())
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import stat
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
@@ -18,6 +20,17 @@ def test_save_config_round_trips(tmp_path: Path) -> None:
|
||||
assert loaded.agents.defaults.model
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.name == "nt", reason="Windows does not expose POSIX file modes")
|
||||
def test_save_config_preserves_existing_file_mode(tmp_path: Path) -> None:
|
||||
path = tmp_path / "config.json"
|
||||
path.write_text("{}", encoding="utf-8")
|
||||
path.chmod(0o600)
|
||||
|
||||
save_config(Config(), path)
|
||||
|
||||
assert stat.S_IMODE(path.stat().st_mode) == 0o600
|
||||
|
||||
|
||||
def test_save_config_preserves_existing_file_when_write_fails(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user