refactor(config): drop legacy config migration (#31)
This commit is contained in:
+5
-43
@@ -1,13 +1,10 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import shutil
|
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
LOCAL_CONFIG_NAME = Path(".takopi") / "takopi.toml"
|
LOCAL_CONFIG_NAME = Path(".takopi") / "takopi.toml"
|
||||||
HOME_CONFIG_PATH = Path.home() / ".takopi" / "takopi.toml"
|
HOME_CONFIG_PATH = Path.home() / ".takopi" / "takopi.toml"
|
||||||
LEGACY_LOCAL_CONFIG_NAME = Path(".codex") / "takopi.toml"
|
|
||||||
LEGACY_HOME_CONFIG_PATH = Path.home() / ".codex" / "takopi.toml"
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigError(RuntimeError):
|
class ConfigError(RuntimeError):
|
||||||
@@ -21,31 +18,6 @@ def _config_candidates() -> list[Path]:
|
|||||||
return candidates
|
return candidates
|
||||||
|
|
||||||
|
|
||||||
def _legacy_candidates() -> list[Path]:
|
|
||||||
candidates = [Path.cwd() / LEGACY_LOCAL_CONFIG_NAME, LEGACY_HOME_CONFIG_PATH]
|
|
||||||
if candidates[0] == candidates[1]:
|
|
||||||
return [candidates[0]]
|
|
||||||
return candidates
|
|
||||||
|
|
||||||
|
|
||||||
def _maybe_migrate_legacy(legacy_path: Path, target_path: Path) -> None:
|
|
||||||
if target_path.exists():
|
|
||||||
if not target_path.is_file():
|
|
||||||
raise ConfigError(
|
|
||||||
f"Config path {target_path} exists but is not a file."
|
|
||||||
) from None
|
|
||||||
return
|
|
||||||
if not legacy_path.is_file():
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
target_path.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
shutil.move(legacy_path, target_path)
|
|
||||||
except OSError as e:
|
|
||||||
raise ConfigError(
|
|
||||||
f"Failed to migrate legacy config {legacy_path} to {target_path}: {e}"
|
|
||||||
) from e
|
|
||||||
|
|
||||||
|
|
||||||
def _read_config(cfg_path: Path) -> dict:
|
def _read_config(cfg_path: Path) -> dict:
|
||||||
try:
|
try:
|
||||||
raw = cfg_path.read_text(encoding="utf-8")
|
raw = cfg_path.read_text(encoding="utf-8")
|
||||||
@@ -65,22 +37,12 @@ def load_telegram_config(path: str | Path | None = None) -> tuple[dict, Path]:
|
|||||||
return _read_config(cfg_path), cfg_path
|
return _read_config(cfg_path), cfg_path
|
||||||
|
|
||||||
config_candidates = _config_candidates()
|
config_candidates = _config_candidates()
|
||||||
legacy_candidates = _legacy_candidates()
|
|
||||||
for legacy, target in zip(legacy_candidates, config_candidates, strict=True):
|
|
||||||
_maybe_migrate_legacy(legacy, target)
|
|
||||||
|
|
||||||
for candidate in config_candidates:
|
for candidate in config_candidates:
|
||||||
|
if candidate.exists() and not candidate.is_file():
|
||||||
|
raise ConfigError(
|
||||||
|
f"Config path {candidate} exists but is not a file."
|
||||||
|
) from None
|
||||||
if candidate.is_file():
|
if candidate.is_file():
|
||||||
return _read_config(candidate), candidate
|
return _read_config(candidate), candidate
|
||||||
|
checked_display = ", ".join(str(candidate) for candidate in config_candidates)
|
||||||
for candidate in legacy_candidates:
|
|
||||||
if candidate.is_file():
|
|
||||||
return _read_config(candidate), candidate
|
|
||||||
|
|
||||||
checked: list[Path] = []
|
|
||||||
for candidate in [*config_candidates, *legacy_candidates]:
|
|
||||||
if candidate in checked:
|
|
||||||
continue
|
|
||||||
checked.append(candidate)
|
|
||||||
checked_display = ", ".join(str(candidate) for candidate in checked)
|
|
||||||
raise ConfigError(f"Missing takopi config. Checked: {checked_display}")
|
raise ConfigError(f"Missing takopi config. Checked: {checked_display}")
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class SetupResult:
|
|||||||
|
|
||||||
|
|
||||||
def config_issue(path: Path) -> SetupIssue:
|
def config_issue(path: Path) -> SetupIssue:
|
||||||
config_display = _config_path_display(_preferred_config_path(path))
|
config_display = _config_path_display(path)
|
||||||
return SetupIssue(
|
return SetupIssue(
|
||||||
"create a config",
|
"create a config",
|
||||||
(
|
(
|
||||||
@@ -82,12 +82,6 @@ def _config_path_display(path: Path) -> str:
|
|||||||
return str(path)
|
return str(path)
|
||||||
|
|
||||||
|
|
||||||
def _preferred_config_path(path: Path) -> Path:
|
|
||||||
if path.name == "takopi.toml" and path.parent.name == ".codex":
|
|
||||||
return path.parent.parent / ".takopi" / "takopi.toml"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def render_setup_guide(result: SetupResult) -> None:
|
def render_setup_guide(result: SetupResult) -> None:
|
||||||
if result.ok:
|
if result.ok:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -51,20 +51,3 @@ def test_check_setup_marks_invalid_chat_id(monkeypatch, tmp_path: Path) -> None:
|
|||||||
|
|
||||||
titles = {issue.title for issue in result.issues}
|
titles = {issue.title for issue in result.issues}
|
||||||
assert "create a config" in titles
|
assert "create a config" in titles
|
||||||
|
|
||||||
|
|
||||||
def test_onboarding_prefers_new_config_path_for_legacy_file(monkeypatch) -> None:
|
|
||||||
backend = engines.get_backend("codex")
|
|
||||||
monkeypatch.setattr(onboarding.shutil, "which", lambda _name: "/usr/bin/codex")
|
|
||||||
legacy_path = Path.home() / ".codex" / "takopi.toml"
|
|
||||||
monkeypatch.setattr(
|
|
||||||
onboarding,
|
|
||||||
"load_telegram_config",
|
|
||||||
lambda: ({"bot_token": "token", "chat_id": "123"}, legacy_path),
|
|
||||||
)
|
|
||||||
|
|
||||||
result = onboarding.check_setup(backend)
|
|
||||||
|
|
||||||
issue = next(issue for issue in result.issues if issue.title == "create a config")
|
|
||||||
assert any("~/.takopi/takopi.toml" in line for line in issue.lines)
|
|
||||||
assert all(".codex/takopi.toml" not in line for line in issue.lines)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user