|
1 | 1 | """DevForge unified CLI entry point.""" |
2 | 2 |
|
3 | | -import builtins as _builtins |
4 | 3 | import subprocess |
5 | 4 | import sys |
6 | 5 | import typer |
@@ -86,7 +85,7 @@ def install( |
86 | 85 | ): |
87 | 86 | """Install a DevForge tool.""" |
88 | 87 | if tool == "all": |
89 | | - targets = _builtins.list(TOOLS.keys()) |
| 88 | + targets = list(TOOLS.keys()) |
90 | 89 | extras = ",".join(TOOLS.keys()) |
91 | 90 | elif tool in TOOLS: |
92 | 91 | targets = [tool] |
@@ -119,7 +118,7 @@ def show_versions( |
119 | 118 | console.print(f"[red]Unknown tool: {tool}[/red]") |
120 | 119 | console.print(f"Available: {', '.join(TOOLS.keys())}") |
121 | 120 | raise typer.Exit(code=1) |
122 | | - targets = [tool] if tool else _builtins.list(TOOLS.keys()) |
| 121 | + targets = [tool] if tool else list(TOOLS.keys()) |
123 | 122 |
|
124 | 123 | for t in targets: |
125 | 124 | info = TOOLS[t] |
@@ -156,15 +155,35 @@ def dispatch( |
156 | 155 | try: |
157 | 156 | result = subprocess.run( |
158 | 157 | [sys.executable, "-m", info["package"].replace("-", "_")] + (args or []), |
159 | | - capture_output=False, |
| 158 | + capture_output=True, |
| 159 | + text=True, |
160 | 160 | ) |
| 161 | + if result.returncode == 0: |
| 162 | + sys.stdout.write(result.stdout) |
| 163 | + if result.stderr: |
| 164 | + sys.stderr.write(result.stderr) |
| 165 | + sys.exit(0) |
| 166 | + # Module not found — show friendly install message |
| 167 | + if "No module named" in result.stderr: |
| 168 | + console.print( |
| 169 | + f"[red]Tool '{tool_name}' not installed.[/red]\n" |
| 170 | + f"Install with: [green]pip install devforge[{tool_name}][/green]" |
| 171 | + ) |
| 172 | + raise typer.Exit(code=1) from None |
| 173 | + # Tool ran but failed — show its output and propagate exit code |
| 174 | + sys.stdout.write(result.stdout) |
| 175 | + sys.stderr.write(result.stderr) |
161 | 176 | sys.exit(result.returncode) |
162 | 177 | except FileNotFoundError: |
| 178 | + # Only reached if sys.executable itself is missing (extremely rare) |
163 | 179 | console.print( |
164 | 180 | f"[red]Tool '{tool_name}' not installed.[/red]\n" |
165 | 181 | f"Install with: [green]pip install devforge-tools[{tool_name}][/green]" |
166 | 182 | ) |
167 | 183 | raise typer.Exit(code=1) from None |
| 184 | + except Exception as e: |
| 185 | + console.print(f"[red]Unexpected error running '{tool_name}': {e}[/red]") |
| 186 | + raise typer.Exit(code=1) from e |
168 | 187 |
|
169 | 188 | dispatch.__name__ = tool_name |
170 | 189 | dispatch.__doc__ = f"Run `{pkg}` commands via the {tool_name} subcommand." |
|
0 commit comments