From 118f46b872a2805d22d19c2a19f24ea45208629b Mon Sep 17 00:00:00 2001 From: sorrow404null Date: Fri, 18 Sep 2026 15:13:58 +0800 Subject: [PATCH] feat(config): add atomic configuration persistence --- core/config_paths.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/core/config_paths.py b/core/config_paths.py index f745429..c04d4c6 100644 --- a/core/config_paths.py +++ b/core/config_paths.py @@ -14,6 +14,7 @@ """ import json import os +import tempfile ENV_KEY = "HAOCODE_CONFIG_FILE" @@ -47,6 +48,37 @@ def load_config() -> dict: return data +def save_config(data: dict) -> bool: + """原子保存当前配置;失败时保留原文件并返回 False。""" + if not isinstance(data, dict): + print("[config] 拒绝保存:配置内容不是 JSON 对象") + return False + + path = os.path.abspath(config_path()) + parent = os.path.dirname(path) + temp_path = "" + try: + os.makedirs(parent, exist_ok=True) + fd, temp_path = tempfile.mkstemp( + prefix=".haocode_config_", suffix=".tmp", dir=parent) + with os.fdopen(fd, "w", encoding="utf-8") as handle: + json.dump(data, handle, ensure_ascii=False, indent=2) + handle.write("\n") + handle.flush() + os.fsync(handle.fileno()) + os.replace(temp_path, path) + return True + except Exception as exc: + print(f"[config] 配置保存失败: {path}({type(exc).__name__})") + return False + finally: + if temp_path and os.path.exists(temp_path): + try: + os.remove(temp_path) + except OSError: + pass + + # ---------------------------------------------------------------------- # P1-01:渲染窗口配置解析(render_window_mode / render_window_size) # 规则(与 ui/web/render_window.js 的 JS 侧守卫保持一致):