Merge pull request #659 from PR0M3TH3AN/codex/update-error-handling-in-gui-command

Add automatic BeeWare backend installation
This commit is contained in:
thePR0M3TH3AN
2025-07-19 15:00:46 -04:00
committed by GitHub
2 changed files with 60 additions and 6 deletions

View File

@@ -26,6 +26,7 @@ from . import api as api_module
import importlib import importlib
import importlib.util import importlib.util
import subprocess
app = typer.Typer( app = typer.Typer(
help="SeedPass command line interface", help="SeedPass command line interface",
@@ -750,11 +751,36 @@ def api_stop(ctx: typer.Context, host: str = "127.0.0.1", port: int = 8000) -> N
@app.command() @app.command()
def gui() -> None: def gui() -> None:
"""Launch the BeeWare GUI.""" """Launch the BeeWare GUI.
If the platform specific backend is missing, attempt to install it and
retry launching the GUI.
"""
if not _gui_backend_available():
if sys.platform.startswith("linux"):
pkg = "toga-gtk"
elif sys.platform == "win32":
pkg = "toga-winforms"
elif sys.platform == "darwin":
pkg = "toga-cocoa"
else:
typer.echo(
f"Unsupported platform '{sys.platform}' for BeeWare GUI.",
err=True,
)
raise typer.Exit(1)
typer.echo(f"Attempting to install {pkg} for GUI support...")
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", pkg])
typer.echo(f"Successfully installed {pkg}.")
except subprocess.CalledProcessError as exc:
typer.echo(f"Failed to install {pkg}: {exc}", err=True)
raise typer.Exit(1)
if not _gui_backend_available(): if not _gui_backend_available():
typer.echo( typer.echo(
"No BeeWare GUI backend found. Install 'toga-gtk' (Linux), " "BeeWare GUI backend still unavailable after installation attempt.",
"'toga-winforms' (Windows) or 'toga-cocoa' (macOS) to run the GUI.",
err=True, err=True,
) )
raise typer.Exit(1) raise typer.Exit(1)

View File

@@ -564,7 +564,35 @@ def test_gui_command(monkeypatch):
def test_gui_command_no_backend(monkeypatch): def test_gui_command_no_backend(monkeypatch):
monkeypatch.setattr(cli.importlib.util, "find_spec", lambda n: None) """Install backend if missing and launch GUI."""
call_count = {"n": 0}
def backend_available() -> bool:
call_count["n"] += 1
return call_count["n"] > 1
monkeypatch.setattr(cli, "_gui_backend_available", backend_available)
installed = {}
def fake_check_call(cmd):
installed["cmd"] = cmd
monkeypatch.setattr(cli.subprocess, "check_call", fake_check_call)
called = {}
def fake_main():
called["gui"] = True
monkeypatch.setitem(
sys.modules,
"seedpass_gui.app",
SimpleNamespace(main=fake_main),
)
result = runner.invoke(app, ["gui"]) result = runner.invoke(app, ["gui"])
assert result.exit_code == 1 assert result.exit_code == 0
assert "BeeWare GUI backend" in result.stderr assert installed.get("cmd") is not None
assert called.get("gui") is True