From ee4d0cf708fdd9e6030da17640e7a70d361a3bc2 Mon Sep 17 00:00:00 2001 From: Brian Krabach Date: Sat, 4 Apr 2026 14:27:51 -0700 Subject: [PATCH] feat: route upgrade command based on install source (PyPI vs git) --- muxplex/cli.py | 9 ++++++-- muxplex/tests/test_cli.py | 48 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/muxplex/cli.py b/muxplex/cli.py index 4cecf1b..7cd605d 100644 --- a/muxplex/cli.py +++ b/muxplex/cli.py @@ -520,6 +520,11 @@ def upgrade(*, force: bool = False) -> None: # 2. Reinstall via uv tool install print(" Installing latest version...") + install_target = ( + "muxplex" + if info["source"] == "pypi" + else "git+https://github.com/bkrabach/muxplex" + ) uv_path = shutil.which("uv") if uv_path: result = subprocess.run( @@ -527,7 +532,7 @@ def upgrade(*, force: bool = False) -> None: uv_path, "tool", "install", - "git+https://github.com/bkrabach/muxplex", + install_target, "--force", ], capture_output=True, @@ -546,7 +551,7 @@ def upgrade(*, force: bool = False) -> None: pip_path, "install", "--upgrade", - "git+https://github.com/bkrabach/muxplex", + install_target, ], capture_output=True, text=True, diff --git a/muxplex/tests/test_cli.py b/muxplex/tests/test_cli.py index 338137a..37e5122 100644 --- a/muxplex/tests/test_cli.py +++ b/muxplex/tests/test_cli.py @@ -2087,3 +2087,51 @@ def test_pyproject_has_keywords(): data = tomllib.loads(pyproject.read_text()) keywords = data["project"].get("keywords", []) assert len(keywords) >= 3 + + +# --------------------------------------------------------------------------- +# task-4-upgrade-routing: upgrade routes based on install source +# --------------------------------------------------------------------------- + + +def test_upgrade_pypi_install_uses_package_name(monkeypatch, capsys): + """upgrade() for PyPI installs must use 'muxplex' not git+https URL.""" + import subprocess + import muxplex.cli as cli_mod + calls = [] + def mock_run(cmd, **kwargs): + calls.append(cmd) + return type("R", (), {"returncode": 0, "stdout": "", "stderr": ""})() + monkeypatch.setattr(subprocess, "run", mock_run) + monkeypatch.setattr(shutil, "which", lambda name: f"/usr/bin/{name}") + monkeypatch.setattr(cli_mod, "doctor", lambda: None) + monkeypatch.setattr(cli_mod, "_get_install_info", lambda: {"source": "pypi", "version": "0.1.0", "commit": None, "url": None}) + monkeypatch.setattr(cli_mod, "_check_for_update", lambda info: (True, "update available (v0.1.0 → v0.2.0)")) + with patch("muxplex.service.service_install", lambda: None): + cli_mod.upgrade() + uv_calls = [c for c in calls if isinstance(c, list) and "tool" in c and "install" in c] + assert len(uv_calls) > 0 + install_cmd = uv_calls[0] + assert "muxplex" in install_cmd + assert not any("git+" in str(arg) for arg in install_cmd) + + +def test_upgrade_git_install_uses_git_url(monkeypatch, capsys): + """upgrade() for git installs must still use git+https URL.""" + import subprocess + import muxplex.cli as cli_mod + calls = [] + def mock_run(cmd, **kwargs): + calls.append(cmd) + return type("R", (), {"returncode": 0, "stdout": "", "stderr": ""})() + monkeypatch.setattr(subprocess, "run", mock_run) + monkeypatch.setattr(shutil, "which", lambda name: f"/usr/bin/{name}") + monkeypatch.setattr(cli_mod, "doctor", lambda: None) + monkeypatch.setattr(cli_mod, "_get_install_info", lambda: {"source": "git", "version": "0.1.0", "commit": "abc12345", "url": "https://github.com/bkrabach/muxplex"}) + monkeypatch.setattr(cli_mod, "_check_for_update", lambda info: (True, "update available (abc12345 → def67890)")) + with patch("muxplex.service.service_install", lambda: None): + cli_mod.upgrade() + uv_calls = [c for c in calls if isinstance(c, list) and "tool" in c and "install" in c] + assert len(uv_calls) > 0 + install_cmd = uv_calls[0] + assert any("git+" in str(arg) for arg in install_cmd)