scheme: fix not saving atomically

Causes programs which rely on the save file (e.g. the shell) to fail occasionally as they try to read while the cli is writing
This commit is contained in:
2 * r + 2 * t
2025-06-12 16:49:01 +10:00
parent dc4b6733bf
commit a53a2568ec
2 changed files with 21 additions and 12 deletions
+10
View File
@@ -1,5 +1,8 @@
import hashlib import hashlib
import json
import os import os
import shutil
import tempfile
from pathlib import Path from pathlib import Path
config_dir = Path(os.getenv("XDG_CONFIG_HOME", Path.home() / ".config")) config_dir = Path(os.getenv("XDG_CONFIG_HOME", Path.home() / ".config"))
@@ -31,3 +34,10 @@ def compute_hash(path: str) -> str:
sha.update(chunk) sha.update(chunk)
return sha.hexdigest() return sha.hexdigest()
def atomic_dump(path: Path, content: dict[str, any]) -> None:
with tempfile.NamedTemporaryFile("w") as f:
json.dump(content, f)
f.flush()
shutil.move(f.name, path)
+11 -12
View File
@@ -3,7 +3,7 @@ import random
from pathlib import Path from pathlib import Path
from caelestia.utils.material import get_colours_for_image from caelestia.utils.material import get_colours_for_image
from caelestia.utils.paths import scheme_data_dir, scheme_path from caelestia.utils.paths import atomic_dump, scheme_data_dir, scheme_path
class Scheme: class Scheme:
@@ -100,17 +100,16 @@ class Scheme:
def save(self) -> None: def save(self) -> None:
scheme_path.parent.mkdir(parents=True, exist_ok=True) scheme_path.parent.mkdir(parents=True, exist_ok=True)
with scheme_path.open("w") as f: atomic_dump(
json.dump( scheme_path,
{ {
"name": self.name, "name": self.name,
"flavour": self.flavour, "flavour": self.flavour,
"mode": self.mode, "mode": self.mode,
"variant": self.variant, "variant": self.variant,
"colours": self.colours, "colours": self.colours,
}, },
f, )
)
def set_random(self) -> None: def set_random(self) -> None:
self._name = random.choice(get_scheme_names()) self._name = random.choice(get_scheme_names())