diff --git a/src/bakrest/config.py b/src/bakrest/config.py index 26beade..4cb78ea 100644 --- a/src/bakrest/config.py +++ b/src/bakrest/config.py @@ -89,7 +89,11 @@ def load_config(path: Path | None = None) -> AppConfig: def load_config_data(path: Path | None = None) -> dict[str, Any]: config_path = ensure_default_config(path) - return tomllib.loads(config_path.read_text(encoding="utf-8")) + data = tomllib.loads(config_path.read_text(encoding="utf-8")) + migrated = migrate_config_data(data) + if migrated: + save_config_data(data, config_path) + return data def save_config_data(data: dict[str, Any], path: Path | None = None) -> Path: @@ -99,6 +103,38 @@ def save_config_data(data: dict[str, Any], path: Path | None = None) -> Path: return config_path +def migrate_config_data(data: dict[str, Any]) -> bool: + backup = data.get("backup") + if not isinstance(backup, dict): + return False + + changed = False + engine = str(backup.get("engine", "robocopy")).lower() + if "engine" not in backup: + backup["engine"] = engine + changed = True + + if engine == "robocopy": + if "robocopy_path" not in backup: + backup["robocopy_path"] = "robocopy" + changed = True + + server_check = backup.setdefault("server_check", {}) + if isinstance(server_check, dict) and int(server_check.get("port", 22)) == 22: + server_check["port"] = 445 + changed = True + + destinations = backup.get("remote_destinations") + if not isinstance(destinations, list): + legacy_destination = str(backup.get("remote_destination", "")).strip() + backup["remote_destinations"] = ( + [legacy_destination] if _is_windows_destination(legacy_destination) else [] + ) + changed = True + + return changed + + def parse_config(data: dict[str, Any], path: Path) -> AppConfig: service = data.get("service", {}) tray = data.get("tray", {}) diff --git a/src/bakrest/config_app.py b/src/bakrest/config_app.py index 236461b..7daed51 100644 --- a/src/bakrest/config_app.py +++ b/src/bakrest/config_app.py @@ -175,8 +175,8 @@ class BakRestConfigApp(ctk.CTk): self.exclude_patterns.set_items(watch.get("exclude_patterns", [])) self.server_host_var.set(str(backup.get("server_host", ""))) - self.server_port_var.set(str(server_check.get("port", 22))) self.engine_var.set(str(backup.get("engine", "robocopy"))) + self.server_port_var.set(str(server_check.get("port", 445 if self.engine_var.get() == "robocopy" else 22))) self.robocopy_path_var.set(str(backup.get("robocopy_path", "robocopy"))) self.remote_destinations.set_items(_configured_destinations(backup)) self.shutdown_on_success_var.set(bool(backup.get("shutdown_on_success", True))) @@ -197,7 +197,8 @@ class BakRestConfigApp(ctk.CTk): backup["remote_destinations"] = self.remote_destinations.items() backup["remote_destination"] = backup["remote_destinations"][0] if backup["remote_destinations"] else "" backup["shutdown_on_success"] = bool(self.shutdown_on_success_var.get()) - server_check["port"] = _safe_int(self.server_port_var.get(), 22) + default_port = 445 if backup["engine"] == "robocopy" else 22 + server_check["port"] = _safe_int(self.server_port_var.get(), default_port) save_config_data(self.data, self.config_path) self.app_config = load_config(self.config_path) diff --git a/tests/test_config_and_filters.py b/tests/test_config_and_filters.py index bd215e8..e92e69e 100644 --- a/tests/test_config_and_filters.py +++ b/tests/test_config_and_filters.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from bakrest.config import parse_config +from bakrest.config import migrate_config_data, parse_config from bakrest.filters import WatchFilter @@ -51,6 +51,24 @@ def test_parse_config_ignores_legacy_rsync_destination_for_robocopy(tmp_path: Pa assert config.backup.remote_destinations == () +def test_migrate_legacy_rsync_config_to_robocopy_defaults() -> None: + data = { + "backup": { + "server_host": "backup-server", + "remote_destination": "utente@backup-server:/backup/bak-rest/", + "server_check": {"type": "tcp", "port": 22}, + } + } + + changed = migrate_config_data(data) + + assert changed + assert data["backup"]["engine"] == "robocopy" + assert data["backup"]["robocopy_path"] == "robocopy" + assert data["backup"]["server_check"]["port"] == 445 + assert data["backup"]["remote_destinations"] == [] + + def test_filter_accepts_included_extension(tmp_path: Path) -> None: config = parse_config( {