mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
fix(settings): preserve template settings file
This commit is contained in:
@@ -66,6 +66,11 @@ class SettingsManager:
|
|||||||
self._needs_initial_save = False
|
self._needs_initial_save = False
|
||||||
self._bootstrap_reason: Optional[str] = None
|
self._bootstrap_reason: Optional[str] = None
|
||||||
self._seed_template: Optional[Dict[str, Any]] = None
|
self._seed_template: Optional[Dict[str, Any]] = None
|
||||||
|
self._template_payload_cache: Optional[Dict[str, Any]] = None
|
||||||
|
self._template_payload_cache_loaded = False
|
||||||
|
self._original_disk_payload: Optional[Dict[str, Any]] = None
|
||||||
|
self._preserve_disk_template = False
|
||||||
|
self._template_path = Path(__file__).resolve().parents[2] / "settings.json.example"
|
||||||
self.settings = self._load_settings()
|
self.settings = self._load_settings()
|
||||||
self._migrate_setting_keys()
|
self._migrate_setting_keys()
|
||||||
self._ensure_default_settings()
|
self._ensure_default_settings()
|
||||||
@@ -89,7 +94,12 @@ class SettingsManager:
|
|||||||
if os.path.exists(self.settings_file):
|
if os.path.exists(self.settings_file):
|
||||||
try:
|
try:
|
||||||
with open(self.settings_file, 'r', encoding='utf-8') as f:
|
with open(self.settings_file, 'r', encoding='utf-8') as f:
|
||||||
return json.load(f)
|
data = json.load(f)
|
||||||
|
if isinstance(data, dict):
|
||||||
|
self._original_disk_payload = copy.deepcopy(data)
|
||||||
|
if self._matches_template_payload(data):
|
||||||
|
self._preserve_disk_template = True
|
||||||
|
return data
|
||||||
except json.JSONDecodeError as exc:
|
except json.JSONDecodeError as exc:
|
||||||
logger.error("Failed to parse settings.json: %s", exc)
|
logger.error("Failed to parse settings.json: %s", exc)
|
||||||
self._add_startup_message(
|
self._add_startup_message(
|
||||||
@@ -133,12 +143,28 @@ class SettingsManager:
|
|||||||
def _load_settings_template(self) -> Optional[Dict[str, Any]]:
|
def _load_settings_template(self) -> Optional[Dict[str, Any]]:
|
||||||
"""Load the bundled template when no user settings are found."""
|
"""Load the bundled template when no user settings are found."""
|
||||||
|
|
||||||
template_path = Path(__file__).resolve().parents[2] / "settings.json.example"
|
payload = self._read_template_payload()
|
||||||
|
if payload is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
self._seed_template = copy.deepcopy(payload)
|
||||||
|
return copy.deepcopy(payload)
|
||||||
|
|
||||||
|
def _read_template_payload(self) -> Optional[Dict[str, Any]]:
|
||||||
|
"""Return the cached contents of ``settings.json.example`` when available."""
|
||||||
|
|
||||||
|
if self._template_payload_cache_loaded:
|
||||||
|
if self._template_payload_cache is None:
|
||||||
|
return None
|
||||||
|
return copy.deepcopy(self._template_payload_cache)
|
||||||
|
|
||||||
|
self._template_payload_cache_loaded = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with template_path.open("r", encoding="utf-8") as handle:
|
with self._template_path.open("r", encoding="utf-8") as handle:
|
||||||
data = json.load(handle)
|
data = json.load(handle)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
logger.debug("settings.json.example not found at %s", template_path)
|
logger.debug("settings.json.example not found at %s", self._template_path)
|
||||||
return None
|
return None
|
||||||
except json.JSONDecodeError as exc:
|
except json.JSONDecodeError as exc:
|
||||||
logger.warning("Failed to parse settings.json.example: %s", exc)
|
logger.warning("Failed to parse settings.json.example: %s", exc)
|
||||||
@@ -148,8 +174,17 @@ class SettingsManager:
|
|||||||
logger.debug("settings.json.example is not a JSON object; ignoring template")
|
logger.debug("settings.json.example is not a JSON object; ignoring template")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
self._seed_template = copy.deepcopy(data)
|
self._template_payload_cache = copy.deepcopy(data)
|
||||||
return copy.deepcopy(data)
|
return copy.deepcopy(self._template_payload_cache)
|
||||||
|
|
||||||
|
def _matches_template_payload(self, payload: Mapping[str, Any]) -> bool:
|
||||||
|
"""Return ``True`` when ``payload`` matches the bundled template."""
|
||||||
|
|
||||||
|
template = self._read_template_payload()
|
||||||
|
if template is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return payload == template
|
||||||
|
|
||||||
def _merge_template_with_defaults(
|
def _merge_template_with_defaults(
|
||||||
self, defaults: Dict[str, Any], template: Mapping[str, Any]
|
self, defaults: Dict[str, Any], template: Mapping[str, Any]
|
||||||
@@ -251,7 +286,7 @@ class SettingsManager:
|
|||||||
self.settings["libraries"] = libraries
|
self.settings["libraries"] = libraries
|
||||||
self.settings["active_library"] = library_name
|
self.settings["active_library"] = library_name
|
||||||
self._sync_active_library_to_root(save=False)
|
self._sync_active_library_to_root(save=False)
|
||||||
if not initial_bootstrap:
|
if not initial_bootstrap and not self._preserve_disk_template:
|
||||||
self._save_settings()
|
self._save_settings()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,12 @@ def read_settings_file(path: Path) -> dict:
|
|||||||
return json.load(handle)
|
return json.load(handle)
|
||||||
|
|
||||||
|
|
||||||
|
def read_example_settings() -> dict:
|
||||||
|
example_path = Path(__file__).resolve().parents[1] / "settings.json.example"
|
||||||
|
with example_path.open('r', encoding='utf-8') as handle:
|
||||||
|
return json.load(handle)
|
||||||
|
|
||||||
|
|
||||||
def test_missing_settings_creates_defaults_and_emits_warnings(tmp_path):
|
def test_missing_settings_creates_defaults_and_emits_warnings(tmp_path):
|
||||||
manager = get_settings_manager()
|
manager = get_settings_manager()
|
||||||
settings_path = Path(manager.settings_file)
|
settings_path = Path(manager.settings_file)
|
||||||
@@ -52,6 +58,20 @@ def test_missing_settings_creates_defaults_and_emits_warnings(tmp_path):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_template_settings_are_preserved_on_restart(tmp_path):
|
||||||
|
manager = get_settings_manager()
|
||||||
|
settings_path = Path(manager.settings_file)
|
||||||
|
|
||||||
|
example_payload = read_example_settings()
|
||||||
|
assert read_settings_file(settings_path) == example_payload
|
||||||
|
|
||||||
|
reset_settings_manager()
|
||||||
|
|
||||||
|
manager = get_settings_manager()
|
||||||
|
assert Path(manager.settings_file) == settings_path
|
||||||
|
assert read_settings_file(settings_path) == example_payload
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_settings_recovers_with_defaults(tmp_path):
|
def test_invalid_settings_recovers_with_defaults(tmp_path):
|
||||||
config_dir = Path(settings_paths.user_config_dir())
|
config_dir = Path(settings_paths.user_config_dir())
|
||||||
config_dir.mkdir(parents=True, exist_ok=True)
|
config_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user