Skip to content

Commit 2a3bc49

Browse files
committed
Doctor cmd check for CF installation
1 parent 67a9e79 commit 2a3bc49

File tree

3 files changed

+199
-0
lines changed

3 files changed

+199
-0
lines changed

codeflash/cli_cmds/cli.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from codeflash.cli_cmds import logging_config
77
from codeflash.cli_cmds.cli_common import apologize_and_exit
88
from codeflash.cli_cmds.cmd_init import init_codeflash, install_github_actions
9+
from codeflash.cli_cmds.cmd_doctor import run_doctor
910
from codeflash.cli_cmds.console import logger
1011
from codeflash.code_utils import env_utils
1112
from codeflash.code_utils.code_utils import exit_with_message
@@ -22,6 +23,9 @@ def parse_args() -> Namespace:
2223

2324
init_actions_parser = subparsers.add_parser("init-actions", help="Initialize GitHub Actions workflow")
2425
init_actions_parser.set_defaults(func=install_github_actions)
26+
27+
doctor_parser = subparsers.add_parser("doctor", help="Verify Codeflash setup and diagnose issues")
28+
doctor_parser.set_defaults(func=run_doctor)
2529
parser.add_argument("--file", help="Try to optimize only this file")
2630
parser.add_argument("--function", help="Try to optimize only this function within the given file path")
2731
parser.add_argument(
@@ -52,6 +56,11 @@ def parse_args() -> Namespace:
5256
action="store_true",
5357
help="Verify that codeflash is set up correctly by optimizing bubble sort as a test.",
5458
)
59+
parser.add_argument(
60+
"--doctor",
61+
action="store_true",
62+
help="Run setup diagnostics to verify Codeflash installation and configuration.",
63+
)
5564
parser.add_argument("-v", "--verbose", action="store_true", help="Print verbose debug logs")
5665
parser.add_argument("--version", action="store_true", help="Print the version of codeflash")
5766
parser.add_argument(

codeflash/cli_cmds/cmd_doctor.py

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
import json
2+
import os
3+
import shutil
4+
import subprocess
5+
import sys
6+
from pathlib import Path
7+
from typing import List, Tuple
8+
9+
from codeflash.cli_cmds.console import logger, paneled_text
10+
from codeflash.version import __version__ as version
11+
12+
13+
def run_doctor() -> None:
14+
"""Run comprehensive setup verification for Codeflash."""
15+
paneled_text(
16+
"🩺 Codeflash Doctor - Diagnosing your setup...",
17+
panel_args={"title": "Setup Verification", "expand": False},
18+
text_args={"style": "bold blue"}
19+
)
20+
21+
checks = [
22+
("Python Environment", check_python_environment),
23+
("Codeflash Installation", check_codeflash_installation),
24+
("VS Code Python Extension", check_vscode_python_extension),
25+
("LSP Server Connection", check_lsp_server_connection),
26+
("Git Repository", check_git_repository),
27+
("Project Configuration", check_project_configuration),
28+
]
29+
30+
results = []
31+
all_passed = True
32+
33+
for check_name, check_func in checks:
34+
logger.info(f"Checking {check_name}...")
35+
success, message = check_func()
36+
results.append((check_name, success, message))
37+
if not success:
38+
all_passed = False
39+
40+
print_results(results, all_passed)
41+
42+
43+
def check_python_environment() -> Tuple[bool, str]:
44+
"""Check Python version and environment."""
45+
try:
46+
python_version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
47+
if sys.version_info < (3, 8):
48+
return False, f"Python {python_version} found. Python 3.8+ required."
49+
return True, f"Python {python_version} ✓"
50+
except Exception as e:
51+
return False, f"Failed to check Python version: {e}"
52+
53+
54+
def check_codeflash_installation() -> Tuple[bool, str]:
55+
"""Verify Codeflash is properly installed."""
56+
try:
57+
return True, f"Codeflash {version} installed ✓"
58+
except Exception as e:
59+
return False, f"Codeflash installation check failed: {e}"
60+
61+
62+
def check_vscode_python_extension() -> Tuple[bool, str]:
63+
"""Check if VS Code Python extension is installed."""
64+
try:
65+
code_cmd = shutil.which("code")
66+
if not code_cmd:
67+
return False, "VS Code 'code' command not found in PATH"
68+
69+
result = subprocess.run(
70+
[code_cmd, "--list-extensions"],
71+
capture_output=True,
72+
text=True,
73+
timeout=10
74+
)
75+
76+
if result.returncode != 0:
77+
return False, f"Failed to list VS Code extensions: {result.stderr}"
78+
79+
extensions = result.stdout.strip().split('\n')
80+
python_extensions = [ext for ext in extensions if 'python' in ext.lower()]
81+
82+
if not python_extensions:
83+
return False, "Python extension not found. Install the Python extension for VS Code."
84+
85+
return True, f"VS Code Python extension found: {', '.join(python_extensions)} ✓"
86+
87+
except subprocess.TimeoutExpired:
88+
return False, "VS Code extension check timed out"
89+
except Exception as e:
90+
return False, f"VS Code extension check failed: {e}"
91+
92+
93+
def check_lsp_server_connection() -> Tuple[bool, str]:
94+
"""Test LSP server connectivity."""
95+
try:
96+
from codeflash.lsp.server import CodeflashLanguageServer
97+
98+
# Test that we can instantiate the server (basic smoke test)
99+
server_class = CodeflashLanguageServer
100+
if hasattr(server_class, 'initialize_optimizer'):
101+
return True, "LSP server available ✓"
102+
else:
103+
return True, "LSP server module loaded successfully ✓"
104+
105+
except ImportError as e:
106+
return False, f"LSP server import failed: {e}"
107+
except Exception as e:
108+
return False, f"LSP server check failed: {e}"
109+
110+
111+
def check_git_repository() -> Tuple[bool, str]:
112+
"""Check if running in a git repository."""
113+
try:
114+
result = subprocess.run(
115+
["git", "rev-parse", "--git-dir"],
116+
capture_output=True,
117+
text=True,
118+
timeout=5
119+
)
120+
121+
if result.returncode == 0:
122+
return True, "Git repository detected ✓"
123+
else:
124+
return False, "No git repository found. Initialize with 'git init'"
125+
126+
except subprocess.TimeoutExpired:
127+
return False, "Git check timed out"
128+
except FileNotFoundError:
129+
return False, "Git not found in PATH"
130+
except Exception as e:
131+
return False, f"Git check failed: {e}"
132+
133+
134+
def check_project_configuration() -> Tuple[bool, str]:
135+
"""Check for project configuration files."""
136+
try:
137+
config_files = ["pyproject.toml", "setup.py", "requirements.txt", "setup.cfg"]
138+
found_configs = []
139+
140+
for config_file in config_files:
141+
if Path(config_file).exists():
142+
found_configs.append(config_file)
143+
144+
if found_configs:
145+
return True, f"Project configuration found: {', '.join(found_configs)} ✓"
146+
else:
147+
return False, "No project configuration files found (pyproject.toml, setup.py, etc.)"
148+
149+
except Exception as e:
150+
return False, f"Project configuration check failed: {e}"
151+
152+
153+
def print_results(results: List[Tuple[str, bool, str]], all_passed: bool) -> None:
154+
"""Print the diagnostic results in a formatted way."""
155+
print("\n" + "="*60)
156+
print("🩺 CODEFLASH SETUP DIAGNOSIS RESULTS")
157+
print("="*60)
158+
159+
for check_name, success, message in results:
160+
status = "✅ PASS" if success else "❌ FAIL"
161+
print(f"{status:8} | {check_name:25} | {message}")
162+
163+
print("="*60)
164+
165+
if all_passed:
166+
paneled_text(
167+
"🎉 Your Codeflash setup is perfect! 🎉\n\n"
168+
"All checks passed successfully. You're ready to optimize your code!\n\n"
169+
"Next steps:\n"
170+
"• Run 'codeflash init' to initialize a project\n"
171+
"• Use 'codeflash --file <filename>' to optimize a specific file\n"
172+
"• Try 'codeflash --verify-setup' for an end-to-end test",
173+
panel_args={"title": "✅ SUCCESS", "expand": False},
174+
text_args={"style": "bold green"}
175+
)
176+
else:
177+
failed_checks = [name for name, success, _ in results if not success]
178+
paneled_text(
179+
f"⚠️ Setup Issues Detected\n\n"
180+
f"The following checks failed:\n"
181+
f"• {chr(10).join(failed_checks)}\n\n"
182+
f"Please address these issues and run 'codeflash doctor' again.\n\n"
183+
f"For help, visit: https://codeflash.ai/docs",
184+
panel_args={"title": "❌ ISSUES FOUND", "expand": False},
185+
text_args={"style": "bold yellow"}
186+
)
187+
sys.exit(1)

codeflash/main.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ def main() -> None:
3535
init_sentry(not args.disable_telemetry, exclude_errors=True)
3636
posthog_cf.initialize_posthog(not args.disable_telemetry)
3737
ask_run_end_to_end_test(args)
38+
elif args.doctor:
39+
from codeflash.cli_cmds.cmd_doctor import run_doctor
40+
run_doctor()
3841
else:
3942
args = process_pyproject_config(args)
4043
args.previous_checkpoint_functions = ask_should_use_checkpoint_get_functions(args)

0 commit comments

Comments
 (0)