Coverage for /Users/antonigmitruk/golf/src/golf/commands/run.py: 0%

1"""Command to run the built FastMCP server."""

2

3 import os

4 import subprocess

5 import sys

6 from pathlib import Path

7

8 from rich.console import Console

9 from rich.panel import Panel

10 from rich.align import Align

11 from rich.text import Text

12

13 from golf.cli.branding import create_command_header, get_status_text, STATUS_ICONS, GOLF_BLUE, GOLF_GREEN, GOLF_ORANGE

14 from golf.core.config import Settings

15

16 console = Console()

17

18

19 def run_server(

20 project_path: Path,

21 settings: Settings,

22 dist_dir: Path | None = None,

23 host: str | None = None,

24 port: int | None = None,

25) -> int:

26 """Run the built FastMCP server.

27

28 Args:

29 project_path: Path to the project root

30 settings: Project settings

31 dist_dir: Path to the directory containing the built server

32 (defaults to project_path/dist)

33 host: Host to bind the server to (overrides settings)

34 port: Port to bind the server to (overrides settings)

35

36 Returns:

37 Process return code

38 """

39 # Set default dist directory if not specified

40 if dist_dir is None:

41 dist_dir = project_path / "dist"

42

43 # Check if server file exists

44 server_path = dist_dir / "server.py"

45 if not server_path.exists():

46 console.print(get_status_text("error", f"Server file {server_path} not found"))

47 return 1

48

49 # Display server startup header

50 create_command_header("Starting Server", f"{settings.name}", console)

51

52 # Show server info with flashy styling

53 server_host = host or settings.host or "localhost"

54 server_port = port or settings.port or 3000

55

56 server_content = Text()

57 server_content.append("🚀 ", style=f"bold {GOLF_ORANGE}")

58 server_content.append(f"{STATUS_ICONS['server']} Server starting on ", style=f"bold {GOLF_BLUE}")

59 server_content.append(f"http://{server_host}:{server_port}", style=f"bold {GOLF_GREEN}")

60 server_content.append(" 🚀", style=f"bold {GOLF_ORANGE}")

61 server_content.append("\n")

62

63 # Add telemetry status indicator

64 if settings.opentelemetry_enabled:

65 server_content.append("📊 Golf telemetry enabled", style=f"dim {GOLF_BLUE}")

66 server_content.append("\n")

67

68 server_content.append("⚡ Press Ctrl+C to stop ⚡", style=f"dim {GOLF_ORANGE}")

69

70 console.print(

71 Panel(

72 Align.center(server_content),

73 border_style=GOLF_BLUE,

74 padding=(1, 2),

75 title="[bold]🌐 SERVER READY 🌐[/bold]",

76 title_align="center",

77 )

78 )

79 console.print()

80

81 # Prepare environment variables

82 env = os.environ.copy()

83 if host is not None:

84 env["HOST"] = host

85 elif settings.host:

86 env["HOST"] = settings.host

87

88 if port is not None:

89 env["PORT"] = str(port)

90 elif settings.port:

91 env["PORT"] = str(settings.port)

92

93 # Run the server

94 try:

95 # Using subprocess to properly handle signals (Ctrl+C)

96 process = subprocess.run(

97 [sys.executable, str(server_path)],

98 cwd=dist_dir,

99 env=env,

100 )

101

102 # Provide more context about the exit

103 console.print()

104 if process.returncode == 0:

105 console.print(get_status_text("success", "Server stopped successfully"))

106 elif process.returncode == 130:

107 console.print(get_status_text("info", "Server stopped by user interrupt (Ctrl+C)"))

108 elif process.returncode == 143:

109 console.print(get_status_text("info", "Server stopped by SIGTERM (graceful shutdown)"))

110 elif process.returncode == 137:

111 console.print(get_status_text("warning", "Server stopped by SIGKILL (forced shutdown)"))

112 elif process.returncode in [1, 2]:

113 console.print(get_status_text("error", f"Server exited with error code {process.returncode}"))

114 else:

115 console.print(get_status_text("warning", f"Server exited with code {process.returncode}"))

116

117 return process.returncode

118 except KeyboardInterrupt:

119 console.print()

120 console.print(get_status_text("info", "Server stopped by user (Ctrl+C)"))

121 return 130 # Standard exit code for SIGINT

122 except Exception as e:

123 console.print()

124 console.print(get_status_text("error", f"Error running server: {e}"))

125 return 1