mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-05-06 16:36:45 -03:00
fix(settings): normalize default root path comparisons
This commit is contained in:
21
py/config.py
21
py/config.py
@@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
import posixpath
|
||||||
import threading
|
import threading
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import folder_paths # type: ignore
|
import folder_paths # type: ignore
|
||||||
@@ -25,6 +26,15 @@ standalone_mode = (
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_root_identity(path: str) -> str:
|
||||||
|
"""Normalize a root path for comparisons across slash styles."""
|
||||||
|
|
||||||
|
normalized = posixpath.normpath(path.strip().replace("\\", "/"))
|
||||||
|
if len(normalized) >= 2 and normalized[1] == ":":
|
||||||
|
return normalized.lower()
|
||||||
|
return normalized
|
||||||
|
|
||||||
|
|
||||||
def _resolve_valid_default_root(
|
def _resolve_valid_default_root(
|
||||||
current: str, primary_paths: List[str], allowed_paths: List[str], name: str
|
current: str, primary_paths: List[str], allowed_paths: List[str], name: str
|
||||||
) -> str:
|
) -> str:
|
||||||
@@ -37,14 +47,17 @@ def _resolve_valid_default_root(
|
|||||||
if not isinstance(path, str):
|
if not isinstance(path, str):
|
||||||
continue
|
continue
|
||||||
stripped = path.strip()
|
stripped = path.strip()
|
||||||
if not stripped or stripped in seen:
|
if not stripped:
|
||||||
continue
|
continue
|
||||||
seen.add(stripped)
|
identity = _normalize_root_identity(stripped)
|
||||||
|
if identity in seen:
|
||||||
|
continue
|
||||||
|
seen.add(identity)
|
||||||
fallback_paths.append(stripped)
|
fallback_paths.append(stripped)
|
||||||
|
|
||||||
allowed = set(fallback_paths)
|
allowed = {_normalize_root_identity(path) for path in fallback_paths}
|
||||||
|
|
||||||
if current and current in allowed:
|
if current and _normalize_root_identity(current) in allowed:
|
||||||
return current
|
return current
|
||||||
|
|
||||||
if not valid_paths:
|
if not valid_paths:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import asyncio
|
|||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import posixpath
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
import logging
|
import logging
|
||||||
@@ -103,6 +104,15 @@ DEFAULT_SETTINGS: Dict[str, Any] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_root_identity(path: str) -> str:
|
||||||
|
"""Normalize a root path for equality checks across slash styles."""
|
||||||
|
|
||||||
|
normalized = posixpath.normpath(path.strip().replace("\\", "/"))
|
||||||
|
if len(normalized) >= 2 and normalized[1] == ":":
|
||||||
|
return normalized.lower()
|
||||||
|
return normalized
|
||||||
|
|
||||||
|
|
||||||
class SettingsManager:
|
class SettingsManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.settings_file = ensure_settings_file(logger)
|
self.settings_file = ensure_settings_file(logger)
|
||||||
@@ -773,7 +783,7 @@ class SettingsManager:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
allowed_roots = self._get_allowed_roots(key)
|
allowed_roots = self._get_allowed_roots(key)
|
||||||
if current and current in allowed_roots:
|
if current and _normalize_root_identity(current) in allowed_roots:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.settings[setting_key] = primary_candidates[0]
|
self.settings[setting_key] = primary_candidates[0]
|
||||||
@@ -824,16 +834,19 @@ class SettingsManager:
|
|||||||
if not isinstance(value, str):
|
if not isinstance(value, str):
|
||||||
continue
|
continue
|
||||||
normalized = value.strip()
|
normalized = value.strip()
|
||||||
if not normalized or normalized in seen:
|
if not normalized:
|
||||||
continue
|
continue
|
||||||
seen.add(normalized)
|
identity = _normalize_root_identity(normalized)
|
||||||
|
if identity in seen:
|
||||||
|
continue
|
||||||
|
seen.add(identity)
|
||||||
candidates.append(normalized)
|
candidates.append(normalized)
|
||||||
return candidates
|
return candidates
|
||||||
|
|
||||||
def _get_allowed_roots(self, key: str) -> set[str]:
|
def _get_allowed_roots(self, key: str) -> set[str]:
|
||||||
"""Return all valid roots for a model type, including extra roots."""
|
"""Return all valid roots for a model type, including extra roots."""
|
||||||
|
|
||||||
return set(self._get_valid_root_candidates(key))
|
return {_normalize_root_identity(path) for path in self._get_valid_root_candidates(key)}
|
||||||
|
|
||||||
def _check_environment_variables(self) -> None:
|
def _check_environment_variables(self) -> None:
|
||||||
"""Check for environment variables and update settings if needed"""
|
"""Check for environment variables and update settings if needed"""
|
||||||
|
|||||||
@@ -402,6 +402,49 @@ def test_save_paths_keeps_default_roots_in_extra_paths(monkeypatch: pytest.Monke
|
|||||||
assert fake_settings.payload["activate"] is True
|
assert fake_settings.payload["activate"] is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_save_paths_keeps_default_roots_in_extra_paths_with_windows_slash_mismatch(
|
||||||
|
monkeypatch: pytest.MonkeyPatch, tmp_path
|
||||||
|
):
|
||||||
|
folder_paths = _setup_config_environment(monkeypatch, tmp_path)
|
||||||
|
|
||||||
|
class FakeSettingsService:
|
||||||
|
active_library = "comfyui"
|
||||||
|
|
||||||
|
def get_libraries(self):
|
||||||
|
return {
|
||||||
|
"comfyui": {
|
||||||
|
"folder_paths": {key: list(value) for key, value in folder_paths.items()},
|
||||||
|
"extra_folder_paths": {
|
||||||
|
"loras": ["U:\\Lora7\\Loras"],
|
||||||
|
"checkpoints": ["U:\\Lora7\\Models"],
|
||||||
|
"embeddings": [],
|
||||||
|
},
|
||||||
|
"default_lora_root": "U:/Lora7/Loras",
|
||||||
|
"default_checkpoint_root": "U:/Lora7/Models",
|
||||||
|
"default_embedding_root": folder_paths["embeddings"][0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def rename_library(self, *_):
|
||||||
|
raise AssertionError("rename_library should not be invoked")
|
||||||
|
|
||||||
|
def get_active_library_name(self):
|
||||||
|
return self.active_library
|
||||||
|
|
||||||
|
def upsert_library(self, name: str, **payload):
|
||||||
|
self.name = name
|
||||||
|
self.payload = payload
|
||||||
|
|
||||||
|
fake_settings = FakeSettingsService()
|
||||||
|
monkeypatch.setattr(settings_manager_module, "settings", fake_settings)
|
||||||
|
|
||||||
|
config_module.Config()
|
||||||
|
|
||||||
|
assert fake_settings.name == "comfyui"
|
||||||
|
assert fake_settings.payload["default_lora_root"] == "U:/Lora7/Loras"
|
||||||
|
assert fake_settings.payload["default_checkpoint_root"] == "U:/Lora7/Models"
|
||||||
|
|
||||||
|
|
||||||
def test_save_paths_repairs_empty_default_roots_to_extra_paths_when_primary_missing(
|
def test_save_paths_repairs_empty_default_roots_to_extra_paths_when_primary_missing(
|
||||||
monkeypatch: pytest.MonkeyPatch, tmp_path
|
monkeypatch: pytest.MonkeyPatch, tmp_path
|
||||||
):
|
):
|
||||||
|
|||||||
@@ -359,6 +359,25 @@ def test_auto_set_default_roots_keeps_valid_extra_values(manager):
|
|||||||
assert manager.get("default_embedding_root") == "/extra-embeddings"
|
assert manager.get("default_embedding_root") == "/extra-embeddings"
|
||||||
|
|
||||||
|
|
||||||
|
def test_auto_set_default_roots_keeps_valid_extra_values_with_windows_slash_mismatch(manager):
|
||||||
|
manager.settings["default_lora_root"] = "U:/Lora7/Loras"
|
||||||
|
manager.settings["default_checkpoint_root"] = "U:/Lora7/Models"
|
||||||
|
|
||||||
|
manager.settings["folder_paths"] = {
|
||||||
|
"loras": ["R:/ComfyUI/models/loras"],
|
||||||
|
"checkpoints": ["R:/ComfyUI/models/checkpoints"],
|
||||||
|
}
|
||||||
|
manager.settings["extra_folder_paths"] = {
|
||||||
|
"loras": ["U:\\Lora7\\Loras"],
|
||||||
|
"checkpoints": ["U:\\Lora7\\Models"],
|
||||||
|
}
|
||||||
|
|
||||||
|
manager._auto_set_default_roots()
|
||||||
|
|
||||||
|
assert manager.get("default_lora_root") == "U:/Lora7/Loras"
|
||||||
|
assert manager.get("default_checkpoint_root") == "U:/Lora7/Models"
|
||||||
|
|
||||||
|
|
||||||
def test_auto_set_default_roots_falls_back_to_extra_when_primary_missing(manager):
|
def test_auto_set_default_roots_falls_back_to_extra_when_primary_missing(manager):
|
||||||
manager.settings["default_lora_root"] = ""
|
manager.settings["default_lora_root"] = ""
|
||||||
manager.settings["folder_paths"] = {"loras": []}
|
manager.settings["folder_paths"] = {"loras": []}
|
||||||
|
|||||||
Reference in New Issue
Block a user