Initial commit: CodeMap v0.1.0 - CLI tool for code analysis and diagram generation
This commit is contained in:
85
codemap/cli/serve.py
Normal file
85
codemap/cli/serve.py
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import webbrowser
|
||||||
|
from pathlib import Path
|
||||||
|
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
||||||
|
from typing import Optional
|
||||||
|
import typer
|
||||||
|
from rich.console import Console
|
||||||
|
from codemap.cli.analyze import _collect_files
|
||||||
|
from codemap.parsers import PythonParser, JavaScriptParser, GoParser
|
||||||
|
from codemap.core import GraphBuilder, MermaidGenerator
|
||||||
|
from codemap.templates import render_html
|
||||||
|
|
||||||
|
console = Console()
|
||||||
|
|
||||||
|
class QuietHTTPHandler(SimpleHTTPRequestHandler):
|
||||||
|
def log_message(self, format, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def serve(
|
||||||
|
path: str = typer.Argument(..., help="Directory to serve"),
|
||||||
|
port: int = typer.Option(8080, "--port", "-p", help="Port to serve on"),
|
||||||
|
open_browser: bool = typer.Option(True, "--open/--no-open", help="Open browser automatically"),
|
||||||
|
) -> None:
|
||||||
|
target_path = Path(path)
|
||||||
|
if not target_path.exists():
|
||||||
|
console.print(f"[red]Error: Path '{path}' does not exist[/red]")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
output_dir = target_path / ".codemap"
|
||||||
|
output_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
html_path = output_dir / "diagram.html"
|
||||||
|
|
||||||
|
def generate_diagram():
|
||||||
|
files = _collect_files(target_path)
|
||||||
|
if not files:
|
||||||
|
return None
|
||||||
|
|
||||||
|
parsers = [PythonParser(), JavaScriptParser(), GoParser()]
|
||||||
|
parsed_files = []
|
||||||
|
|
||||||
|
for file_path in files:
|
||||||
|
for parser in parsers:
|
||||||
|
if parser.can_parse(file_path):
|
||||||
|
try:
|
||||||
|
parsed = parser.parse(file_path)
|
||||||
|
parsed_files.append(parsed)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
break
|
||||||
|
|
||||||
|
builder = GraphBuilder()
|
||||||
|
builder.build_from_files(parsed_files)
|
||||||
|
|
||||||
|
graph_data = builder.get_graph_data()
|
||||||
|
mermaid_gen = MermaidGenerator(graph_data)
|
||||||
|
return render_html(mermaid_gen.generate_flowchart(), title=f"Code Map: {path}", auto_refresh=True, refresh_interval=5)
|
||||||
|
|
||||||
|
with console.status("[bold green]Generating diagram...[/bold green]") as status:
|
||||||
|
html_content = generate_diagram()
|
||||||
|
|
||||||
|
if html_content:
|
||||||
|
html_path.write_text(html_content, encoding="utf-8")
|
||||||
|
|
||||||
|
os.chdir(str(output_dir))
|
||||||
|
server = HTTPServer(('localhost', port), QuietHTTPHandler)
|
||||||
|
|
||||||
|
url = f"http://localhost:{port}/diagram.html"
|
||||||
|
console.print(f"[bold green]Serving at: {url}[/bold green]")
|
||||||
|
console.print(f"[dim]Diagram file: {html_path}[/dim]")
|
||||||
|
console.print("[dim]Press Ctrl+C to stop[/dim]")
|
||||||
|
|
||||||
|
if open_browser:
|
||||||
|
threading.Timer(1.0, lambda: webbrowser.open(url)).start()
|
||||||
|
|
||||||
|
try:
|
||||||
|
server.serve_forever()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
console.print("\n[yellow]Stopping server...[/yellow]")
|
||||||
|
server.shutdown()
|
||||||
|
else:
|
||||||
|
console.print("[yellow]No files found to analyze[/yellow]")
|
||||||
Reference in New Issue
Block a user