Coverage for src/jtech_installer/cli/main_backup.py: 0%

344 statements  

« 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""" 

6 

7import sys 

8import time 

9from pathlib import Path 

10 

11import click 

12from rich.console import Console 

13from rich.panel import Panel 

14from rich.progress import Progress, SpinnerColumn, TextColumn 

15from rich.table import Table 

16 

17from ..core.engine import InstallationEngine 

18from ..core.models import InstallationConfig, InstallationType, TeamType 

19from ..validator.integrity import IntegrityValidator 

20from ..validator.post_installation import PostInstallationValidator 

21 

22console = Console() 

23 

24 

25@click.group(invoke_without_command=True) 

26@click.option("--help", "-h", is_flag=True, help="Mostrar ajuda") 

27@click.option("--version", "-v", is_flag=True, help="Mostrar versão") 

28@click.option( 

29 "--team", 

30 "-t", 

31 type=click.Choice(["ide-minimal", "fullstack", "no-ui", "all"]), 

32 default="fullstack", 

33 help="Tipo de equipe/configuração", 

34) 

35@click.option("--force", "-f", is_flag=True, help="Forçar reinstalação") 

36@click.option( 

37 "--validate-only", is_flag=True, help="Apenas validar instalação existente" 

38) 

39@click.pass_context 

40def cli(ctx, help, version, team, force, validate_only): 

41 """ 

42 🚀 JTECH™ Core Installer 

43 

44 Instala e configura automaticamente o ambiente JTECH™ Core no projeto atual. 

45 

46 Exemplos: 

47 jtech-installer # Instala com configuração fullstack 

48 jtech-installer --team ide-minimal # Instala configuração mínima 

49 jtech-installer --validate-only # Apenas valida instalação 

50 jtech-installer --help # Mostra esta ajuda 

51 """ 

52 

53 if version: 

54 console.print("🚀 JTECH™ Core Installer v0.1.0", style="bold blue") 

55 return 

56 

57 if help or ctx.invoked_subcommand is not None: 

58 if help: 

59 console.print(ctx.get_help()) 

60 return 

61 

62 # Comando principal - instalar 

63 project_path = Path.cwd() 

64 

65 console.print( 

66 Panel.fit( 

67 "[bold blue]🚀 JTECH™ Core Installer[/bold blue]\n" 

68 f"📁 Projeto: [cyan]{ project_path} [/cyan]\n" 

69 f"⚙️ Tipo de equipe: [green]{ team} [/green]", 

70 title="🔧 Configuração", 

71 border_style="blue", 

72 ) 

73 ) 

74 

75 if validate_only: 

76 return validate_installation(project_path, team) 

77 

78 return install_jtech_core(project_path, team, force) 

79 

80 

81def install_jtech_core( 

82 project_path: Path, team_type: str, force: bool = False 

83): 

84 """Executa a instalação completa do JTECH™ Core.""" 

85 

86 # Verificar se já existe instalação 

87 jtech_core = project_path / ".jtech-core" 

88 if jtech_core.exists() and not force: 

89 console.print("⚠️ Instalação JTECH™ Core já existe!", style="yellow") 

90 console.print("💡 Use --force para reinstalar", style="dim") 

91 

92 if not click.confirm("Deseja continuar e atualizar a instalação?"): 

93 console.print("❌ Instalação cancelada", style="red") 

94 return False 

95 

96 # Mapear tipo de equipe 

97 team_mapping = { 

98 "ide-minimal": TeamType.IDE_MINIMAL, 

99 "fullstack": TeamType.FULLSTACK, 

100 "no-ui": TeamType.NO_UI, 

101 "all": TeamType.ALL, 

102 } 

103 

104 team_enum = team_mapping[team_type] 

105 

106 # Determinar tipo de instalação 

107 install_type = ( 

108 InstallationType.BROWNFIELD 

109 if any( 

110 p.exists() 

111 for p in [ 

112 project_path / "package.json", 

113 project_path / "requirements.txt", 

114 project_path / "pom.xml", 

115 project_path / "Cargo.toml", 

116 ] 

117 ) 

118 else InstallationType.GREENFIELD 

119 ) 

120 

121 # Criar configuração 

122 config = InstallationConfig( 

123 project_path=project_path, 

124 install_type=install_type, 

125 team_type=team_enum, 

126 vs_code_integration=True, 

127 custom_config={}, 

128 framework_source_path=get_framework_source_path(), 

129 ) 

130 

131 # Executar instalação com progress 

132 with Progress( 

133 SpinnerColumn(), 

134 TextColumn("[progress.description]{task.description}"), 

135 console=console, 

136 ) as progress: 

137 

138 # Passo 1: Criar estrutura 

139 task = progress.add_task( 

140 "🏗️ Criando estrutura de diretórios...", total=None 

141 ) 

142 engine = InstallationEngine() 

143 

144 try: 

145 # Instalar 

146 result = engine.install(config) 

147 progress.update(task, description="✅ Estrutura criada") 

148 time.sleep(0.5) 

149 

150 # Passo 2: Copiar chatmodes reais 

151 progress.update(task, description="💬 Configurando chatmodes...") 

152 copy_real_chatmodes(project_path) 

153 time.sleep(0.5) 

154 

155 # Passo 3: Configurar VS Code real 

156 progress.update(task, description="🔧 Configurando VS Code...") 

157 copy_real_vscode_config(project_path) 

158 time.sleep(0.5) 

159 

160 # Passo 4: Validar 

161 progress.update(task, description="🔍 Validando instalação...") 

162 validator = PostInstallationValidator(config) 

163 report = validator.validate_all() 

164 

165 progress.remove_task(task) 

166 

167 except Exception as e: 

168 progress.remove_task(task) 

169 console.print(f"❌ Erro durante instalação: {e}", style="red") 

170 return False 

171 

172 # Mostrar resultado 

173 show_installation_result(report, project_path) 

174 return True 

175 

176 

177def copy_real_chatmodes(project_path: Path): 

178 """Copia os chatmodes reais do ambiente do usuário.""" 

179 source_chatmodes = Path( 

180 "/jtech/home/angelo.vicente/code/jtech-kpi/.github/chatmodes" 

181 ) 

182 target_chatmodes = project_path / ".github" / "chatmodes" 

183 

184 if not source_chatmodes.exists(): 

185 console.print("⚠️ Chatmodes de origem não encontrados", style="yellow") 

186 return 

187 

188 # Criar diretório target 

189 target_chatmodes.mkdir(parents=True, exist_ok=True) 

190 

191 # Copiar todos os arquivos .chatmode.md 

192 import shutil 

193 

194 copied_files = [] 

195 

196 for chatmode_file in source_chatmodes.glob("*.chatmode.md"): 

197 target_file = target_chatmodes / chatmode_file.name 

198 shutil.copy2(chatmode_file, target_file) 

199 copied_files.append(chatmode_file.name) 

200 

201 console.print(f"✅ Copiados {len(copied_files)} chatmodes", style="green") 

202 

203 

204def copy_real_vscode_config(project_path: Path): 

205 """Copia a configuração real do VS Code do ambiente do usuário.""" 

206 source_vscode = Path( 

207 "/jtech/home/angelo.vicente/code/jtech-kpi/.vscode/settings.json" 

208 ) 

209 target_vscode_dir = project_path / ".vscode" 

210 target_vscode_file = target_vscode_dir / "settings.json" 

211 

212 if not source_vscode.exists(): 

213 console.print( 

214 "⚠️ Configuração VS Code de origem não encontrada", style="yellow" 

215 ) 

216 return 

217 

218 # Criar diretório target 

219 target_vscode_dir.mkdir(parents=True, exist_ok=True) 

220 

221 # Copiar configuração 

222 import shutil 

223 

224 shutil.copy2(source_vscode, target_vscode_file) 

225 

226 console.print("✅ Configuração VS Code copiada", style="green") 

227 

228 

229def get_framework_source_path() -> Path: 

230 """Retorna o caminho para os arquivos fonte do framework.""" 

231 # Por enquanto, usar o diretório do próprio installer 

232 installer_dir = Path(__file__).parent.parent.parent.parent 

233 framework_dir = installer_dir / "framework" 

234 

235 if framework_dir.exists(): 

236 return framework_dir 

237 

238 # Fallback para diretório de templates 

239 return installer_dir / "templates" 

240 

241 

242def validate_installation(project_path: Path, team_type: str): 

243 """Valida uma instalação existente.""" 

244 console.print("🔍 Validando instalação JTECH™ Core...", style="blue") 

245 

246 # Verificar se existe instalação 

247 jtech_core = project_path / ".jtech-core" 

248 if not jtech_core.exists(): 

249 console.print( 

250 "❌ Nenhuma instalação JTECH™ Core encontrada", style="red" 

251 ) 

252 console.print( 

253 "💡 Execute 'jtech-installer' para instalar", style="dim" 

254 ) 

255 return False 

256 

257 # Mapear tipo de equipe 

258 team_mapping = { 

259 "ide-minimal": TeamType.IDE_MINIMAL, 

260 "fullstack": TeamType.FULLSTACK, 

261 "no-ui": TeamType.NO_UI, 

262 "all": TeamType.ALL, 

263 } 

264 

265 # Criar configuração para validação 

266 config = InstallationConfig( 

267 project_path=project_path, 

268 install_type=InstallationType.BROWNFIELD, 

269 team_type=team_mapping[team_type], 

270 vs_code_integration=True, 

271 custom_config={}, 

272 framework_source_path=get_framework_source_path(), 

273 ) 

274 

275 # Executar validação 

276 with Progress( 

277 SpinnerColumn(), 

278 TextColumn("[progress.description]{task.description}"), 

279 console=console, 

280 ) as progress: 

281 task = progress.add_task("🔍 Executando validação...", total=None) 

282 

283 try: 

284 # Validação pós-instalação 

285 validator = PostInstallationValidator(config) 

286 report = validator.validate_all() 

287 

288 # Validação de integridade 

289 integrity_validator = IntegrityValidator(config) 

290 integrity_valid = integrity_validator.validate_all() 

291 

292 progress.remove_task(task) 

293 

294 except Exception as e: 

295 progress.remove_task(task) 

296 console.print(f"❌ Erro durante validação: {e}", style="red") 

297 return False 

298 

299 # Mostrar resultado da validação 

300 show_validation_result(report, integrity_valid, project_path) 

301 return report.is_valid 

302 

303 

304def show_installation_result(report, project_path: Path): 

305 """Mostra o resultado da instalação.""" 

306 

307 if report.is_valid: 

308 console.print( 

309 Panel.fit( 

310 "[bold green]🎉 INSTALAÇÃO CONCLUÍDA COM SUCESSO![/bold green]\n\n" 

311 f"📁 Projeto: [cyan]{ project_path} [/cyan]\n" 

312 f"🔧 Estrutura: [green].jtech-core/[/green] criada\n" 

313 f"💬 ChatModes: [green].github/chatmodes/[/green] configurados\n" 

314 f"⚙️ VS Code: [green].vscode/settings.json[/green] configurado", 

315 title="✅ Sucesso", 

316 border_style="green", 

317 ) 

318 ) 

319 

320 # Mostrar próximos passos 

321 next_steps = Table(title="📋 Próximos Passos") 

322 next_steps.add_column("Comando", style="cyan") 

323 next_steps.add_column("Descrição", style="white") 

324 

325 next_steps.add_row("code .", "Abrir projeto no VS Code") 

326 next_steps.add_row( 

327 "jtech-installer --validate-only", "Validar instalação" 

328 ) 

329 next_steps.add_row("ls .jtech-core/", "Explorar estrutura criada") 

330 

331 console.print(next_steps) 

332 

333 else: 

334 console.print( 

335 Panel.fit( 

336 "[bold yellow]⚠️ INSTALAÇÃO COM AVISOS[/bold yellow]\n\n" 

337 f"📁 Projeto: [cyan]{ project_path} [/cyan]\n" 

338 f"🔍 Validações: [red]{ len([r for r in report.components if not r.is_valid])} [/red] falharam", 

339 title="⚠️ Atenção", 

340 border_style="yellow", 

341 ) 

342 ) 

343 

344 

345def show_validation_result(report, integrity_valid: bool, project_path: Path): 

346 """Mostra o resultado da validação.""" 

347 

348 # Tabela de resultados 

349 table = Table(title="🔍 Resultado da Validação") 

350 table.add_column("Componente", style="cyan") 

351 table.add_column("Status", style="white") 

352 table.add_column("Detalhes", style="dim") 

353 

354 # Adicionar resultados individuais 

355 for result in report.components: 

356 status = "✅ OK" if result.is_valid else "❌ FALHA" 

357 table.add_row(result.component, status, result.message or "") 

358 

359 # Adicionar integridade 

360 integrity_status = "✅ OK" if integrity_valid else "❌ FALHA" 

361 table.add_row("Integridade", integrity_status, "Verificação de checksums") 

362 

363 console.print(table) 

364 

365 # Resultado geral 

366 if report.is_valid and integrity_valid: 

367 console.print( 

368 "\n🎉 [bold green]Instalação válida e íntegra![/bold green]" 

369 ) 

370 else: 

371 console.print( 

372 "\n⚠️ [bold yellow]Instalação com problemas detectados[/bold yellow]" 

373 ) 

374 

375 

376@cli.command() 

377def validate(): 

378 """Valida a instalação JTECH™ Core no diretório atual.""" 

379 project_path = Path.cwd() 

380 return validate_installation(project_path, "fullstack") 

381 

382 

383@cli.command() 

384@click.option( 

385 "--team", 

386 "-t", 

387 type=click.Choice(["ide-minimal", "fullstack", "no-ui", "all"]), 

388 default="fullstack", 

389) 

390def install(team): 

391 """Instala JTECH™ Core no diretório atual.""" 

392 project_path = Path.cwd() 

393 return install_jtech_core(project_path, team, force=False) 

394 

395 

396@cli.command() 

397@click.option( 

398 "--team", 

399 "-t", 

400 type=click.Choice(["ide-minimal", "fullstack", "no-ui", "all"]), 

401 default="fullstack", 

402) 

403def reinstall(team): 

404 """Reinstala JTECH™ Core (força reinstalação).""" 

405 project_path = Path.cwd() 

406 return install_jtech_core(project_path, team, force=True) 

407 

408 

409def main(): 

410 """Ponto de entrada principal.""" 

411 try: 

412 cli() 

413 except KeyboardInterrupt: 

414 console.print("\n❌ Operação cancelada pelo usuário", style="red") 

415 sys.exit(1) 

416 except Exception as e: 

417 console.print(f"\n❌ Erro inesperado: {e}", style="red") 

418 sys.exit(1) 

419 

420 

421if __name__ == "__main__": 

422 main() 

423 

424import sys 

425import time 

426from pathlib import Path 

427 

428import click 

429from rich.console import Console 

430from rich.panel import Panel 

431from rich.progress import Progress, SpinnerColumn, TextColumn 

432from rich.table import Table 

433 

434from ..core.engine import InstallationEngine 

435from ..core.models import InstallationConfig, InstallationType, TeamType 

436from ..validator.integrity import IntegrityValidator 

437from ..validator.post_installation import PostInstallationValidator 

438 

439console = Console() 

440 

441 

442@click.group(invoke_without_command=True) 

443@click.option("--help", "-h", is_flag=True, help="Mostrar ajuda") 

444@click.option("--version", "-v", is_flag=True, help="Mostrar versão") 

445@click.option( 

446 "--team", 

447 "-t", 

448 type=click.Choice(["ide-minimal", "fullstack", "no-ui", "all"]), 

449 default="fullstack", 

450 help="Tipo de equipe/configuração", 

451) 

452@click.option("--force", "-f", is_flag=True, help="Forçar reinstalação") 

453@click.option( 

454 "--validate-only", is_flag=True, help="Apenas validar instalação existente" 

455) 

456@click.pass_context 

457def cli(ctx, help, version, team, force, validate_only): 

458 """ 

459 🚀 JTECH™ Core Installer 

460 

461 Instala e configura automaticamente o ambiente JTECH™ Core no projeto atual. 

462 

463 Exemplos: 

464 jtech-installer # Instala com configuração fullstack 

465 jtech-installer --team ide-minimal # Instala configuração mínima 

466 jtech-installer --validate-only # Apenas valida instalação 

467 jtech-installer --help # Mostra esta ajuda 

468 """ 

469 

470 if version: 

471 console.print("🚀 JTECH™ Core Installer v0.1.0", style="bold blue") 

472 return 

473 

474 if help or ctx.invoked_subcommand is not None: 

475 if help: 

476 console.print(ctx.get_help()) 

477 return 

478 

479 # Comando principal - instalar 

480 project_path = Path.cwd() 

481 

482 console.print( 

483 Panel.fit( 

484 "[bold blue]🚀 JTECH™ Core Installer[/bold blue]\n" 

485 f"📁 Projeto: [cyan]{project_path}[/cyan]\n" 

486 f"⚙️ Tipo de equipe: [green]{team}[/green]", 

487 title="🔧 Configuração", 

488 border_style="blue", 

489 ) 

490 ) 

491 

492 if validate_only: 

493 return validate_installation(project_path, team) 

494 

495 return install_jtech_core(project_path, team, force) 

496 

497 

498def install_jtech_core( 

499 project_path: Path, team_type: str, force: bool = False 

500): 

501 """Executa a instalação completa do JTECH™ Core.""" 

502 

503 # Verificar se já existe instalação 

504 jtech_core = project_path / ".jtech-core" 

505 if jtech_core.exists() and not force: 

506 console.print("⚠️ Instalação JTECH™ Core já existe!", style="yellow") 

507 console.print("💡 Use --force para reinstalar", style="dim") 

508 

509 if not click.confirm("Deseja continuar e atualizar a instalação?"): 

510 console.print("❌ Instalação cancelada", style="red") 

511 return False 

512 

513 # Mapear tipo de equipe 

514 team_mapping = { 

515 "ide-minimal": TeamType.IDE_MINIMAL, 

516 "fullstack": TeamType.FULLSTACK, 

517 "no-ui": TeamType.NO_UI, 

518 "all": TeamType.ALL, 

519 } 

520 

521 team_enum = team_mapping[team_type] 

522 

523 # Determinar tipo de instalação 

524 install_type = ( 

525 InstallationType.BROWNFIELD 

526 if any( 

527 p.exists() 

528 for p in [ 

529 project_path / "package.json", 

530 project_path / "requirements.txt", 

531 project_path / "pom.xml", 

532 project_path / "Cargo.toml", 

533 ] 

534 ) 

535 else InstallationType.GREENFIELD 

536 ) 

537 

538 # Criar configuração 

539 config = InstallationConfig( 

540 project_path=project_path, 

541 install_type=install_type, 

542 team_type=team_enum, 

543 vs_code_integration=True, 

544 custom_config={}, 

545 framework_source_path=get_framework_source_path(), 

546 ) 

547 

548 # Executar instalação com progress 

549 with Progress( 

550 SpinnerColumn(), 

551 TextColumn("[progress.description]{task.description}"), 

552 console=console, 

553 ) as progress: 

554 

555 # Passo 1: Criar estrutura 

556 task = progress.add_task( 

557 "🏗️ Criando estrutura de diretórios...", total=None 

558 ) 

559 engine = InstallationEngine() 

560 

561 try: 

562 # Instalar 

563 result = engine.install(config) 

564 progress.update(task, description="✅ Estrutura criada") 

565 time.sleep(0.5) 

566 

567 # Passo 2: Copiar chatmodes reais 

568 progress.update(task, description="💬 Configurando chatmodes...") 

569 copy_real_chatmodes(project_path) 

570 time.sleep(0.5) 

571 

572 # Passo 3: Configurar VS Code real 

573 progress.update(task, description="🔧 Configurando VS Code...") 

574 copy_real_vscode_config(project_path) 

575 time.sleep(0.5) 

576 

577 # Passo 4: Validar 

578 progress.update(task, description="🔍 Validando instalação...") 

579 validator = PostInstallationValidator(config) 

580 report = validator.validate_all() 

581 

582 progress.remove_task(task) 

583 

584 except Exception as e: 

585 progress.remove_task(task) 

586 console.print(f"❌ Erro durante instalação: {e}", style="red") 

587 return False 

588 

589 # Mostrar resultado 

590 show_installation_result(report, project_path) 

591 return True 

592 

593 

594def copy_real_chatmodes(project_path: Path): 

595 """Copia os chatmodes reais do ambiente do usuário.""" 

596 source_chatmodes = Path( 

597 "/jtech/home/angelo.vicente/code/jtech-kpi/.github/chatmodes" 

598 ) 

599 target_chatmodes = project_path / ".github" / "chatmodes" 

600 

601 if not source_chatmodes.exists(): 

602 console.print("⚠️ Chatmodes de origem não encontrados", style="yellow") 

603 return 

604 

605 # Criar diretório target 

606 target_chatmodes.mkdir(parents=True, exist_ok=True) 

607 

608 # Copiar todos os arquivos .chatmode.md 

609 import shutil 

610 

611 copied_files = [] 

612 

613 for chatmode_file in source_chatmodes.glob("*.chatmode.md"): 

614 target_file = target_chatmodes / chatmode_file.name 

615 shutil.copy2(chatmode_file, target_file) 

616 copied_files.append(chatmode_file.name) 

617 

618 console.print(f"✅ Copiados {len(copied_files)} chatmodes", style="green") 

619 

620 

621def copy_real_vscode_config(project_path: Path): 

622 """Copia a configuração real do VS Code do ambiente do usuário.""" 

623 source_vscode = Path( 

624 "/jtech/home/angelo.vicente/code/jtech-kpi/.vscode/settings.json" 

625 ) 

626 target_vscode_dir = project_path / ".vscode" 

627 target_vscode_file = target_vscode_dir / "settings.json" 

628 

629 if not source_vscode.exists(): 

630 console.print( 

631 "⚠️ Configuração VS Code de origem não encontrada", style="yellow" 

632 ) 

633 return 

634 

635 # Criar diretório target 

636 target_vscode_dir.mkdir(parents=True, exist_ok=True) 

637 

638 # Copiar configuração 

639 import shutil 

640 

641 shutil.copy2(source_vscode, target_vscode_file) 

642 

643 console.print("✅ Configuração VS Code copiada", style="green") 

644 

645 

646def get_framework_source_path() -> Path: 

647 """Retorna o caminho para os arquivos fonte do framework.""" 

648 # Por enquanto, usar o diretório do próprio installer 

649 installer_dir = Path(__file__).parent.parent.parent.parent 

650 framework_dir = installer_dir / "framework" 

651 

652 if framework_dir.exists(): 

653 return framework_dir 

654 

655 # Fallback para diretório de templates 

656 return installer_dir / "templates" 

657 

658 

659def validate_installation(project_path: Path, team_type: str): 

660 """Valida uma instalação existente.""" 

661 console.print("🔍 Validando instalação JTECH™ Core...", style="blue") 

662 

663 # Verificar se existe instalação 

664 jtech_core = project_path / ".jtech-core" 

665 if not jtech_core.exists(): 

666 console.print( 

667 "❌ Nenhuma instalação JTECH™ Core encontrada", style="red" 

668 ) 

669 console.print( 

670 "💡 Execute 'jtech-installer' para instalar", style="dim" 

671 ) 

672 return False 

673 

674 # Mapear tipo de equipe 

675 team_mapping = { 

676 "ide-minimal": TeamType.IDE_MINIMAL, 

677 "fullstack": TeamType.FULLSTACK, 

678 "no-ui": TeamType.NO_UI, 

679 "all": TeamType.ALL, 

680 } 

681 

682 # Criar configuração para validação 

683 config = InstallationConfig( 

684 project_path=project_path, 

685 install_type=InstallationType.BROWNFIELD, 

686 team_type=team_mapping[team_type], 

687 vs_code_integration=True, 

688 custom_config={}, 

689 framework_source_path=get_framework_source_path(), 

690 ) 

691 

692 # Executar validação 

693 with Progress( 

694 SpinnerColumn(), 

695 TextColumn("[progress.description]{task.description}"), 

696 console=console, 

697 ) as progress: 

698 task = progress.add_task("🔍 Executando validação...", total=None) 

699 

700 try: 

701 # Validação pós-instalação 

702 validator = PostInstallationValidator(config) 

703 report = validator.validate_all() 

704 

705 # Validação de integridade 

706 integrity_validator = IntegrityValidator(config) 

707 integrity_valid = integrity_validator.validate_all() 

708 

709 progress.remove_task(task) 

710 

711 except Exception as e: 

712 progress.remove_task(task) 

713 console.print(f"❌ Erro durante validação: {e}", style="red") 

714 return False 

715 

716 # Mostrar resultado da validação 

717 show_validation_result(report, integrity_valid, project_path) 

718 return report.is_valid 

719 

720 

721def show_installation_result(report, project_path: Path): 

722 """Mostra o resultado da instalação.""" 

723 

724 if report.is_valid: 

725 console.print( 

726 Panel.fit( 

727 "[bold green]🎉 INSTALAÇÃO CONCLUÍDA COM SUCESSO![/bold green]\n\n" 

728 f"📁 Projeto: [cyan]{project_path}[/cyan]\n" 

729 f"🔧 Estrutura: [green].jtech-core/[/green] criada\n" 

730 f"💬 ChatModes: [green].github/chatmodes/[/green] configurados\n" 

731 f"⚙️ VS Code: [green].vscode/settings.json[/green] configurado", 

732 title="✅ Sucesso", 

733 border_style="green", 

734 ) 

735 ) 

736 

737 # Mostrar próximos passos 

738 next_steps = Table(title="📋 Próximos Passos") 

739 next_steps.add_column("Comando", style="cyan") 

740 next_steps.add_column("Descrição", style="white") 

741 

742 next_steps.add_row("code .", "Abrir projeto no VS Code") 

743 next_steps.add_row( 

744 "jtech-installer --validate-only", "Validar instalação" 

745 ) 

746 next_steps.add_row("ls .jtech-core/", "Explorar estrutura criada") 

747 

748 console.print(next_steps) 

749 

750 else: 

751 console.print( 

752 Panel.fit( 

753 "[bold yellow]⚠️ INSTALAÇÃO COM AVISOS[/bold yellow]\n\n" 

754 f"📁 Projeto: [cyan]{project_path}[/cyan]\n" 

755 f"🔍 Validações: [red]{len([r for r in report.components if not r.is_valid])}[/red] falharam", 

756 title="⚠️ Atenção", 

757 border_style="yellow", 

758 ) 

759 ) 

760 

761 

762def show_validation_result(report, integrity_valid: bool, project_path: Path): 

763 """Mostra o resultado da validação.""" 

764 

765 # Tabela de resultados 

766 table = Table(title="🔍 Resultado da Validação") 

767 table.add_column("Componente", style="cyan") 

768 table.add_column("Status", style="white") 

769 table.add_column("Detalhes", style="dim") 

770 

771 # Adicionar resultados individuais 

772 for result in report.components: 

773 status = "✅ OK" if result.is_valid else "❌ FALHA" 

774 table.add_row(result.component, status, result.message or "") 

775 

776 # Adicionar integridade 

777 integrity_status = "✅ OK" if integrity_valid else "❌ FALHA" 

778 table.add_row("Integridade", integrity_status, "Verificação de checksums") 

779 

780 console.print(table) 

781 

782 # Resultado geral 

783 if report.is_valid and integrity_valid: 

784 console.print( 

785 "\n🎉 [bold green]Instalação válida e íntegra![/bold green]" 

786 ) 

787 else: 

788 console.print( 

789 "\n⚠️ [bold yellow]Instalação com problemas detectados[/bold yellow]" 

790 ) 

791 

792 

793@cli.command() 

794def validate(): 

795 """Valida a instalação JTECH™ Core no diretório atual.""" 

796 project_path = Path.cwd() 

797 return validate_installation(project_path, "fullstack") 

798 

799 

800@cli.command() 

801@click.option( 

802 "--team", 

803 "-t", 

804 type=click.Choice(["ide-minimal", "fullstack", "no-ui", "all"]), 

805 default="fullstack", 

806) 

807def install(team): 

808 """Instala JTECH™ Core no diretório atual.""" 

809 project_path = Path.cwd() 

810 return install_jtech_core(project_path, team, force=False) 

811 

812 

813@cli.command() 

814@click.option( 

815 "--team", 

816 "-t", 

817 type=click.Choice(["ide-minimal", "fullstack", "no-ui", "all"]), 

818 default="fullstack", 

819) 

820def reinstall(team): 

821 """Reinstala JTECH™ Core (força reinstalação).""" 

822 project_path = Path.cwd() 

823 return install_jtech_core(project_path, team, force=True) 

824 

825 

826def main(): 

827 """Ponto de entrada principal.""" 

828 try: 

829 cli() 

830 except KeyboardInterrupt: 

831 console.print("\n❌ Operação cancelada pelo usuário", style="red") 

832 sys.exit(1) 

833 except Exception as e: 

834 console.print(f"\n❌ Erro inesperado: {e}", style="red") 

835 sys.exit(1) 

836 

837 

838if __name__ == "__main__": 

839 main()