feat(sdlc-rename): отказ CLI при каталоге данных под прежним именем
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
08460dc281
commit
d643007c0b
@ -31,6 +31,12 @@ def main(argv=None) -> int:
|
|||||||
p.add_argument("path")
|
p.add_argument("path")
|
||||||
args = ap.parse_args(argv)
|
args = ap.parse_args(argv)
|
||||||
|
|
||||||
|
if (problem := paths.home_problem()):
|
||||||
|
print(problem, file=sys.stderr)
|
||||||
|
return 2
|
||||||
|
if (warning := paths.home_warning()):
|
||||||
|
print(warning, file=sys.stderr)
|
||||||
|
|
||||||
if args.cmd == "agent":
|
if args.cmd == "agent":
|
||||||
from . import release
|
from . import release
|
||||||
names = [m.name for m in registry.agent_modules()]
|
names = [m.name for m in registry.agent_modules()]
|
||||||
|
|||||||
@ -10,6 +10,27 @@ def home() -> Path:
|
|||||||
return Path(os.environ.get("SDLC_HUB_HOME", str(Path.home() / ".local" / "share" / "sdlc-hub")))
|
return Path(os.environ.get("SDLC_HUB_HOME", str(Path.home() / ".local" / "share" / "sdlc-hub")))
|
||||||
|
|
||||||
|
|
||||||
|
def legacy_home() -> Path:
|
||||||
|
"""Каталог данных под прежним именем (до переименования в sdlc-hub)."""
|
||||||
|
return Path.home() / ".local" / "share" / "jira-hub"
|
||||||
|
|
||||||
|
|
||||||
|
def home_problem() -> "str | None":
|
||||||
|
"""Текст отказа, если данные лежат только под прежним именем; при заданном SDLC_HUB_HOME проверки нет."""
|
||||||
|
if os.environ.get("SDLC_HUB_HOME") or home().exists() or not legacy_home().exists():
|
||||||
|
return None
|
||||||
|
return ("каталог данных хаба лежит под прежним именем ~/.local/share/jira-hub; перенесите его: "
|
||||||
|
"bash scripts/cutover.sh (или mv ~/.local/share/jira-hub ~/.local/share/sdlc-hub при остановленном хабе)")
|
||||||
|
|
||||||
|
|
||||||
|
def home_warning() -> "str | None":
|
||||||
|
"""Предупреждение, если существуют оба каталога (SDLC_HUB_HOME не задан)."""
|
||||||
|
if os.environ.get("SDLC_HUB_HOME") or not (home().exists() and legacy_home().exists()):
|
||||||
|
return None
|
||||||
|
return ("есть и ~/.local/share/sdlc-hub, и ~/.local/share/jira-hub: работаю с новым, "
|
||||||
|
"прежний каталог ~/.local/share/jira-hub можно удалить после проверки")
|
||||||
|
|
||||||
|
|
||||||
def db_path() -> Path:
|
def db_path() -> Path:
|
||||||
return home() / "hub.sqlite"
|
return home() / "hub.sqlite"
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,12 @@ from sdlc_hub.modules.jira import project_fields
|
|||||||
from sdlc_hub.modules.jira import projects as jira_projects
|
from sdlc_hub.modules.jira import projects as jira_projects
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def _isolated_home(monkeypatch, tmp_path_factory):
|
||||||
|
"""HOME — во временный каталог: на результат не влияют реальные ~/.local/share/{jira,sdlc}-hub разработчика."""
|
||||||
|
monkeypatch.setenv("HOME", str(tmp_path_factory.mktemp("home")))
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def open_db():
|
def open_db():
|
||||||
"""Фабрика соединений: open_db() — база в памяти, open_db(path) — файл. Все закрываются после теста."""
|
"""Фабрика соединений: open_db() — база в памяти, open_db(path) — файл. Все закрываются после теста."""
|
||||||
|
|||||||
@ -2,6 +2,8 @@ import json
|
|||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from sdlc_hub.core import api, cli, paths, release, settings
|
from sdlc_hub.core import api, cli, paths, release, settings
|
||||||
|
|
||||||
FIXTURE = Path(__file__).parent / "fixtures" / "config.example.json"
|
FIXTURE = Path(__file__).parent / "fixtures" / "config.example.json"
|
||||||
@ -103,3 +105,34 @@ def test_agent_publish_migrates_old_layout(tmp_path, monkeypatch, capsys):
|
|||||||
assert cli.main(["agent", "publish", str(new)]) == 1 # v13 < v14: «только вверх» видит прежнюю публикацию
|
assert cli.main(["agent", "publish", str(new)]) == 1 # v13 < v14: «только вверх» видит прежнюю публикацию
|
||||||
assert not (rel / "agent.py").exists() and not (rel / "manifest.json").exists()
|
assert not (rel / "agent.py").exists() and not (rel / "manifest.json").exists()
|
||||||
assert json.loads((rel / "jira" / "manifest.json").read_text(encoding="utf-8"))["version"] == 14
|
assert json.loads((rel / "jira" / "manifest.json").read_text(encoding="utf-8"))["version"] == 14
|
||||||
|
|
||||||
|
|
||||||
|
def _homes(monkeypatch, tmp_path, legacy=True, new=False):
|
||||||
|
monkeypatch.delenv("SDLC_HUB_HOME", raising=False)
|
||||||
|
monkeypatch.setenv("HOME", str(tmp_path))
|
||||||
|
share = tmp_path / ".local" / "share"
|
||||||
|
if legacy: (share / "jira-hub").mkdir(parents=True)
|
||||||
|
if new: (share / "sdlc-hub").mkdir(parents=True)
|
||||||
|
return share
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("argv", [["serve"], ["tokens"], ["mcp", "jira"], ["agent", "publish", "x.py"]])
|
||||||
|
def test_legacy_home_refused(monkeypatch, tmp_path, capsys, argv):
|
||||||
|
share = _homes(monkeypatch, tmp_path)
|
||||||
|
assert cli.main(argv) == 2
|
||||||
|
err = capsys.readouterr().err
|
||||||
|
assert "~/.local/share/jira-hub" in err and "scripts/cutover.sh" in err
|
||||||
|
assert not (share / "sdlc-hub").exists()
|
||||||
|
assert sorted(p.name for p in (share / "jira-hub").iterdir()) == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_both_homes_warn(monkeypatch, tmp_path, capsys):
|
||||||
|
_homes(monkeypatch, tmp_path, new=True)
|
||||||
|
cli.main(["tokens"])
|
||||||
|
assert "прежний каталог ~/.local/share/jira-hub можно удалить" in capsys.readouterr().err
|
||||||
|
|
||||||
|
|
||||||
|
def test_env_home_skips_legacy_check(monkeypatch, tmp_path, capsys):
|
||||||
|
_homes(monkeypatch, tmp_path)
|
||||||
|
monkeypatch.setenv("SDLC_HUB_HOME", str(tmp_path / "x"))
|
||||||
|
assert cli.main(["tokens"]) == 0
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user