summaryrefslogtreecommitdiff
path: root/src/caelestia/utils
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-06-12 16:49:01 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-06-12 16:49:01 +1000
commita53a2568ec6e4e53d32a48443f50eee9d9fb8fcd (patch)
tree73a2ecf05724309738f783fc5ed20514768fc624 /src/caelestia/utils
parentmaterial: better mono scheme (diff)
downloadcaelestia-cli-a53a2568ec6e4e53d32a48443f50eee9d9fb8fcd.tar.gz
caelestia-cli-a53a2568ec6e4e53d32a48443f50eee9d9fb8fcd.tar.bz2
caelestia-cli-a53a2568ec6e4e53d32a48443f50eee9d9fb8fcd.zip
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
Diffstat (limited to '')
-rw-r--r--src/caelestia/utils/paths.py10
-rw-r--r--src/caelestia/utils/scheme.py23
2 files changed, 21 insertions, 12 deletions
diff --git a/src/caelestia/utils/paths.py b/src/caelestia/utils/paths.py
index 6a6e0a8..3b5a7a6 100644
--- a/src/caelestia/utils/paths.py
+++ b/src/caelestia/utils/paths.py
@@ -1,5 +1,8 @@
import hashlib
+import json
import os
+import shutil
+import tempfile
from pathlib import Path
config_dir = Path(os.getenv("XDG_CONFIG_HOME", Path.home() / ".config"))
@@ -31,3 +34,10 @@ def compute_hash(path: str) -> str:
sha.update(chunk)
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)
diff --git a/src/caelestia/utils/scheme.py b/src/caelestia/utils/scheme.py
index c978231..9027589 100644
--- a/src/caelestia/utils/scheme.py
+++ b/src/caelestia/utils/scheme.py
@@ -3,7 +3,7 @@ import random
from pathlib import Path
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:
@@ -100,17 +100,16 @@ class Scheme:
def save(self) -> None:
scheme_path.parent.mkdir(parents=True, exist_ok=True)
- with scheme_path.open("w") as f:
- json.dump(
- {
- "name": self.name,
- "flavour": self.flavour,
- "mode": self.mode,
- "variant": self.variant,
- "colours": self.colours,
- },
- f,
- )
+ atomic_dump(
+ scheme_path,
+ {
+ "name": self.name,
+ "flavour": self.flavour,
+ "mode": self.mode,
+ "variant": self.variant,
+ "colours": self.colours,
+ },
+ )
def set_random(self) -> None:
self._name = random.choice(get_scheme_names())