feat: wire service subcommand group into CLI (install, uninstall, start, stop, restart, status, logs)
This commit is contained in:
@@ -707,6 +707,18 @@ def main() -> None:
|
||||
"--system", action="store_true", help="System-wide (requires sudo)"
|
||||
)
|
||||
|
||||
service_parser = sub.add_parser(
|
||||
"service", help="Manage the muxplex background service"
|
||||
)
|
||||
service_sub = service_parser.add_subparsers(dest="service_command")
|
||||
service_sub.add_parser("install", help="Install + enable + start the service")
|
||||
service_sub.add_parser("uninstall", help="Stop + disable + remove the service")
|
||||
service_sub.add_parser("start", help="Start the service")
|
||||
service_sub.add_parser("stop", help="Stop the service")
|
||||
service_sub.add_parser("restart", help="Stop + start the service")
|
||||
service_sub.add_parser("status", help="Show service status")
|
||||
service_sub.add_parser("logs", help="Tail service logs")
|
||||
|
||||
sub.add_parser("show-password", help="Show the current muxplex password")
|
||||
|
||||
sub.add_parser(
|
||||
@@ -743,6 +755,34 @@ def main() -> None:
|
||||
doctor()
|
||||
elif args.command in ("upgrade", "update"):
|
||||
upgrade(force=getattr(args, "force", False))
|
||||
elif args.command == "service":
|
||||
from muxplex.service import ( # noqa: PLC0415
|
||||
service_install,
|
||||
service_logs,
|
||||
service_restart,
|
||||
service_start,
|
||||
service_status,
|
||||
service_stop,
|
||||
service_uninstall,
|
||||
)
|
||||
|
||||
cmd = getattr(args, "service_command", None)
|
||||
if cmd == "install":
|
||||
service_install()
|
||||
elif cmd == "uninstall":
|
||||
service_uninstall()
|
||||
elif cmd == "start":
|
||||
service_start()
|
||||
elif cmd == "stop":
|
||||
service_stop()
|
||||
elif cmd == "restart":
|
||||
service_restart()
|
||||
elif cmd == "status":
|
||||
service_status()
|
||||
elif cmd == "logs":
|
||||
service_logs()
|
||||
else:
|
||||
service_parser.print_help()
|
||||
else:
|
||||
_check_dependencies()
|
||||
serve(
|
||||
|
||||
@@ -1025,3 +1025,96 @@ def test_doctor_shows_serve_config(tmp_path, monkeypatch, capsys):
|
||||
assert "0.0.0.0" in out
|
||||
assert "9999" in out
|
||||
assert "password" in out
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# service subcommand dispatch tests
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_service_install_dispatches():
|
||||
"""muxplex service install must call service_install()."""
|
||||
from muxplex.cli import main
|
||||
|
||||
with patch("muxplex.service.service_install") as mock_fn:
|
||||
with patch("sys.argv", ["muxplex", "service", "install"]):
|
||||
main()
|
||||
mock_fn.assert_called_once()
|
||||
|
||||
|
||||
def test_service_uninstall_dispatches():
|
||||
"""muxplex service uninstall must call service_uninstall()."""
|
||||
from muxplex.cli import main
|
||||
|
||||
with patch("muxplex.service.service_uninstall") as mock_fn:
|
||||
with patch("sys.argv", ["muxplex", "service", "uninstall"]):
|
||||
main()
|
||||
mock_fn.assert_called_once()
|
||||
|
||||
|
||||
def test_service_start_dispatches():
|
||||
"""muxplex service start must call service_start()."""
|
||||
from muxplex.cli import main
|
||||
|
||||
with patch("muxplex.service.service_start") as mock_fn:
|
||||
with patch("sys.argv", ["muxplex", "service", "start"]):
|
||||
main()
|
||||
mock_fn.assert_called_once()
|
||||
|
||||
|
||||
def test_service_stop_dispatches():
|
||||
"""muxplex service stop must call service_stop()."""
|
||||
from muxplex.cli import main
|
||||
|
||||
with patch("muxplex.service.service_stop") as mock_fn:
|
||||
with patch("sys.argv", ["muxplex", "service", "stop"]):
|
||||
main()
|
||||
mock_fn.assert_called_once()
|
||||
|
||||
|
||||
def test_service_restart_dispatches():
|
||||
"""muxplex service restart must call service_restart()."""
|
||||
from muxplex.cli import main
|
||||
|
||||
with patch("muxplex.service.service_restart") as mock_fn:
|
||||
with patch("sys.argv", ["muxplex", "service", "restart"]):
|
||||
main()
|
||||
mock_fn.assert_called_once()
|
||||
|
||||
|
||||
def test_service_status_dispatches():
|
||||
"""muxplex service status must call service_status()."""
|
||||
from muxplex.cli import main
|
||||
|
||||
with patch("muxplex.service.service_status") as mock_fn:
|
||||
with patch("sys.argv", ["muxplex", "service", "status"]):
|
||||
main()
|
||||
mock_fn.assert_called_once()
|
||||
|
||||
|
||||
def test_service_logs_dispatches():
|
||||
"""muxplex service logs must call service_logs()."""
|
||||
from muxplex.cli import main
|
||||
|
||||
with patch("muxplex.service.service_logs") as mock_fn:
|
||||
with patch("sys.argv", ["muxplex", "service", "logs"]):
|
||||
main()
|
||||
mock_fn.assert_called_once()
|
||||
|
||||
|
||||
def test_service_subcommand_in_help():
|
||||
"""'service' must appear in muxplex --help output."""
|
||||
import io
|
||||
|
||||
from muxplex.cli import main
|
||||
|
||||
buf = io.StringIO()
|
||||
with patch("sys.argv", ["muxplex", "--help"]):
|
||||
try:
|
||||
with patch("sys.stdout", buf):
|
||||
main()
|
||||
except SystemExit:
|
||||
pass
|
||||
|
||||
help_text = buf.getvalue().lower()
|
||||
assert "service" in help_text
|
||||
|
||||
Reference in New Issue
Block a user