Coverage for src/jtech_installer/cli/main_clean.py: 0%
157 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-08-20 15:10 -0300
« prev ^ index » next coverage.py v7.8.0, created at 2025-08-20 15:10 -0300
1#!/usr/bin/env python3
2"""
3🚀 JTECH™ Core Installer - CLI Principal
4Instalador automatizado para configurar ambiente JTECH™ Core
5"""
7import shutil
8import sys
9import time
10from pathlib import Path
12import click
13from rich.console import Console
14from rich.panel import Panel
15from rich.progress import Progress, SpinnerColumn, TextColumn
16from rich.table import Table
18console = Console()
21@click.group(invoke_without_command=True)
22@click.option("--help", "-h", is_flag=True, help="Mostrar ajuda")
23@click.option("--version", "-v", is_flag=True, help="Mostrar versão")
24@click.option(
25 "--team",
26 "-t",
27 type=click.Choice(["ide-minimal", "fullstack", "no-ui", "all"]),
28 default="fullstack",
29 help="Tipo de equipe/configuração",
30)
31@click.option("--force", "-f", is_flag=True, help="Forçar reinstalação")
32@click.option(
33 "--validate-only", is_flag=True, help="Apenas validar instalação existente"
34)
35@click.pass_context
36def cli(ctx, help, version, team, force, validate_only):
37 """
38 🚀 JTECH™ Core Installer
40 Instala e configura automaticamente o ambiente JTECH™ Core
41 no projeto atual.
43 Exemplos:
44 jtech-installer # Instala com configuração fullstack
45 jtech-installer --team ide-minimal # Instala configuração mínima
46 jtech-installer --validate-only # Apenas valida instalação
47 jtech-installer --help # Mostra esta ajuda
48 """
50 if version:
51 console.print("🚀 JTECH™ Core Installer v0.1.0", style="bold blue")
52 return
54 if help or ctx.invoked_subcommand is not None:
55 if help:
56 console.print(ctx.get_help())
57 return
59 # Comando principal - instalar
60 project_path = Path.cwd()
62 console.print(
63 Panel.fit(
64 f"[bold blue]🚀 JTECH™ Core Installer[/bold blue]\n"
65 f"📁 Projeto: [cyan]{project_path}[/cyan]\n"
66 f"⚙️ Tipo de equipe: [green]{team}[/green]",
67 title="🔧 Configuração",
68 border_style="blue",
69 )
70 )
72 if validate_only:
73 return validate_installation(project_path, team)
75 return install_jtech_core(project_path, team, force)
78def install_jtech_core(
79 project_path: Path, team_type: str, force: bool = False
80):
81 """Executa a instalação completa do JTECH™ Core."""
83 # Verificar se já existe instalação
84 jtech_core = project_path / ".jtech-core"
85 if jtech_core.exists() and not force:
86 console.print("⚠️ Instalação JTECH™ Core já existe!", style="yellow")
87 console.print("💡 Use --force para reinstalar", style="dim")
89 if not click.confirm("Deseja continuar e atualizar a instalação?"):
90 console.print("❌ Instalação cancelada", style="red")
91 return False
93 # Executar instalação com progress
94 with Progress(
95 SpinnerColumn(),
96 TextColumn("[progress.description]{task.description}"),
97 console=console,
98 ) as progress:
100 task = progress.add_task("🏗️ Iniciando instalação...", total=None)
102 try:
103 # Passo 1: Copiar estrutura .jtech-core completa
104 progress.update(task, description="📦 Copiando framework...")
105 copy_jtech_core_structure(project_path, force)
106 time.sleep(0.5)
108 # Passo 2: Copiar chatmodes
109 progress.update(task, description="💬 Configurando chatmodes...")
110 copy_chatmodes(project_path)
111 time.sleep(0.5)
113 # Passo 3: Configurar VS Code
114 progress.update(task, description="🔧 Configurando VS Code...")
115 copy_vscode_config(project_path)
116 time.sleep(0.5)
118 # Passo 4: Finalizar
119 progress.update(task, description="🔍 Finalizando...")
120 time.sleep(0.5)
122 progress.remove_task(task)
124 except Exception as e:
125 progress.remove_task(task)
126 console.print(f"❌ Erro durante instalação: {e}", style="red")
127 return False
129 # Mostrar resultado
130 show_installation_result(True, project_path)
131 return True
134def copy_jtech_core_structure(project_path: Path, force: bool = False):
135 """Copia toda a estrutura .jtech-core dos assets empacotados."""
136 assets_dir = Path(__file__).parent.parent / "assets"
137 source_jtech = assets_dir / ".jtech-core"
138 target_jtech = project_path / ".jtech-core"
140 if not source_jtech.exists():
141 console.print(
142 "⚠️ Estrutura .jtech-core não encontrada nos assets", style="yellow"
143 )
144 return
146 # Copiar toda a estrutura
147 if target_jtech.exists() and force:
148 shutil.rmtree(target_jtech)
150 if not target_jtech.exists():
151 shutil.copytree(source_jtech, target_jtech)
152 console.print(
153 "✅ Estrutura .jtech-core copiada dos assets", style="green"
154 )
155 else:
156 console.print("✅ Estrutura .jtech-core já existe", style="green")
159def copy_chatmodes(project_path: Path):
160 """Copia os chatmodes dos assets empacotados."""
161 assets_dir = Path(__file__).parent.parent / "assets"
162 source_chatmodes = assets_dir / ".github" / "chatmodes"
163 target_chatmodes = project_path / ".github" / "chatmodes"
165 if not source_chatmodes.exists():
166 console.print("⚠️ Chatmodes não encontrados nos assets", style="yellow")
167 return
169 # Criar diretório target
170 target_chatmodes.mkdir(parents=True, exist_ok=True)
172 # Copiar todos os arquivos .chatmode.md
173 copied_files = []
175 for chatmode_file in source_chatmodes.glob("*.chatmode.md"):
176 target_file = target_chatmodes / chatmode_file.name
177 shutil.copy2(chatmode_file, target_file)
178 copied_files.append(chatmode_file.name)
180 console.print(
181 f"✅ Copiados {len(copied_files)} chatmodes dos assets", style="green"
182 )
185def copy_vscode_config(project_path: Path):
186 """Copia a configuração do VS Code dos assets empacotados."""
187 assets_dir = Path(__file__).parent.parent / "assets"
188 source_vscode = assets_dir / ".vscode" / "settings.json"
189 target_vscode_dir = project_path / ".vscode"
190 target_vscode_file = target_vscode_dir / "settings.json"
192 if not source_vscode.exists():
193 console.print(
194 "⚠️ Configuração VS Code não encontrada nos assets", style="yellow"
195 )
196 return
198 # Criar diretório target
199 target_vscode_dir.mkdir(parents=True, exist_ok=True)
201 # Copiar configuração
202 shutil.copy2(source_vscode, target_vscode_file)
204 console.print("✅ Configuração VS Code copiada dos assets", style="green")
207def validate_installation(project_path: Path, team_type: str):
208 """Valida uma instalação existente."""
209 console.print("🔍 Validando instalação JTECH™ Core...", style="blue")
211 # Verificar se existe instalação
212 jtech_core = project_path / ".jtech-core"
213 if not jtech_core.exists():
214 console.print(
215 "❌ Nenhuma instalação JTECH™ Core encontrada", style="red"
216 )
217 console.print(
218 "💡 Execute 'jtech-installer' para instalar", style="dim"
219 )
220 return False
222 # Verificar componentes principais
223 components = [
224 (".jtech-core", "Estrutura principal"),
225 (".jtech-core/agents", "Agentes"),
226 (".jtech-core/tasks", "Tarefas"),
227 (".jtech-core/templates", "Templates"),
228 (".github/chatmodes", "ChatModes"),
229 (".vscode/settings.json", "Configuração VS Code"),
230 ]
232 # Tabela de resultados
233 table = Table(title="🔍 Resultado da Validação")
234 table.add_column("Componente", style="cyan")
235 table.add_column("Status", style="white")
237 all_valid = True
239 for component_path, component_name in components:
240 full_path = project_path / component_path
241 if full_path.exists():
242 status = "✅ OK"
243 else:
244 status = "❌ FALTA"
245 all_valid = False
247 table.add_row(component_name, status)
249 console.print(table)
251 # Resultado geral
252 if all_valid:
253 console.print("\n🎉 [bold green]Instalação válida![/bold green]")
254 else:
255 console.print(
256 "\n⚠️ [bold yellow]Alguns componentes estão faltando[/bold yellow]"
257 )
259 return all_valid
262def show_installation_result(success: bool, project_path: Path):
263 """Mostra o resultado da instalação."""
265 if success:
266 console.print(
267 Panel.fit(
268 "[bold green]🎉 INSTALAÇÃO CONCLUÍDA COM SUCESSO![/bold green]\n\n"
269 f"📁 Projeto: [cyan]{project_path}[/cyan]\n"
270 f"🔧 Estrutura: [green].jtech-core/[/green] criada\n"
271 f"💬 ChatModes: [green].github/chatmodes/[/green] configurados\n"
272 f"⚙️ VS Code: [green].vscode/settings.json[/green] configurado",
273 title="✅ Sucesso",
274 border_style="green",
275 )
276 )
278 # Mostrar próximos passos
279 next_steps = Table(title="📋 Próximos Passos")
280 next_steps.add_column("Comando", style="cyan")
281 next_steps.add_column("Descrição", style="white")
283 next_steps.add_row("code .", "Abrir projeto no VS Code")
284 next_steps.add_row(
285 "jtech-installer --validate-only", "Validar instalação"
286 )
287 next_steps.add_row("ls .jtech-core/", "Explorar estrutura criada")
289 console.print(next_steps)
291 else:
292 console.print(
293 Panel.fit(
294 "[bold yellow]⚠️ INSTALAÇÃO COM PROBLEMAS[/bold yellow]\n\n"
295 f"📁 Projeto: [cyan]{project_path}[/cyan]\n"
296 f"🔍 Verifique os logs acima",
297 title="⚠️ Atenção",
298 border_style="yellow",
299 )
300 )
303@cli.command()
304def validate():
305 """Valida a instalação JTECH™ Core no diretório atual."""
306 project_path = Path.cwd()
307 return validate_installation(project_path, "fullstack")
310@cli.command()
311@click.option(
312 "--team",
313 "-t",
314 type=click.Choice(["ide-minimal", "fullstack", "no-ui", "all"]),
315 default="fullstack",
316)
317def install(team):
318 """Instala JTECH™ Core no diretório atual."""
319 project_path = Path.cwd()
320 return install_jtech_core(project_path, team, force=False)
323@cli.command()
324@click.option(
325 "--team",
326 "-t",
327 type=click.Choice(["ide-minimal", "fullstack", "no-ui", "all"]),
328 default="fullstack",
329)
330def reinstall(team):
331 """Reinstala JTECH™ Core (força reinstalação)."""
332 project_path = Path.cwd()
333 return install_jtech_core(project_path, team, force=True)
336def main():
337 """Ponto de entrada principal."""
338 try:
339 cli()
340 except KeyboardInterrupt:
341 console.print("\n❌ Operação cancelada pelo usuário", style="red")
342 sys.exit(1)
343 except Exception as e:
344 console.print(f"\n❌ Erro inesperado: {e}", style="red")
345 sys.exit(1)
348if __name__ == "__main__":
349 main()