listadetarefas-painel.ps1)Objetivo: Centralizar o gerenciamento do ecossistema com um painel de controle para iniciar e parar todos os serviços de forma rápida e fácil.
listadetarefas-painel.ps1.Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
projeto-todolist/
├── listadetarefas.api/
├── listadetarefas-web/
├── listadetarefas-desktop/
├── listadetarefas-android/
└── listadetarefas-painel.ps1 # <- Script de automação
Copie o código abaixo para o seu arquivo listadetarefas-painel.ps1. Ele está corrigido para usar os nomes corretos dos projetos, é portátil e verifica se os projetos precisam ser construídos antes de executar.
#
# SYNOPSIS
# Painel de controle para gerenciar o projeto To-Do List (API, Web, Desktop, Mobile).
#
# DESCRIPTION
# Este script PowerShell fornece um menu interativo para iniciar, parar, construir e
# depurar os diferentes componentes do projeto no Windows.
#
# VERSION
# 4.3 - Versão PowerShell com detecção e seleção dinâmica de emuladores Android.
#
#==============================================================================
# --- CONFIGURAÇÕES GLOBAIS ---
#==============================================================================
$basePath = $PSScriptRoot
$apiPath = "$basePath\listadetarefas.api"
$webPath = "$basePath\listadetarefas-web"
$desktopPath = "$basePath\listadetarefas-desktop"
$androidPath = "$basePath\listadetarefas-android"
$sdkPath = "C:\Users\$env:UserName\AppData\Local\Android\Sdk" # Ajuste se necessário
$emulatorPath = "$sdkPath\emulator"
$platformToolsPath = "$sdkPath\platform-tools"
$emulatorName = "" # Definido dinamicamente
$availableEmulators = @()
$androidPackage = "br.com.curso.listadetarefas.android"
$desktopWindowTitle = "Minha Lista de Tarefas (Desktop)"
$apiJar = "$apiPath\target\listadetarefas.api-0.0.1-SNAPSHOT.jar"
$desktopJar = "$desktopPath\target\listadetarefas-desktop-1.0-SNAPSHOT.jar"
$webUrl = "http://localhost:4200"
#==============================================================================
# --- VERIFICAÇÃO DE PRÉ-REQUISITOS ---
#==============================================================================
function Test-Dependencies {
$missing = @() if (-not (Get-Command adb.exe -ErrorAction SilentlyContinue) -and -not (Test-Path "$platformToolsPath\adb.exe")) {
$missing += "adb (Android Platform Tools)" } if (-not (Get-Command java.exe -ErrorAction SilentlyContinue)) {$missing += "java"
}
if ($missing.Count -ne 0) { Write-Host "ERRO: Ferramentas necessárias não encontradas:$($missing -join ', ')." -ForegroundColor Red Write-Host "Instale-as e/ou ajuste `$sdkPath no início deste script." -ForegroundColor Yellow
exit 1
}
}
#==============================================================================
# --- FUNÇÕES DE SELEÇÃO DE EMULADOR ---
#==============================================================================
function Initialize-EmulatorSelection {
Write-Host "Detectando emuladores instalados..." -ForegroundColor Cyan
if (-not (Test-Path "$emulatorPath\emulator.exe")) { Write-Host "AVISO: Executável do emulador não encontrado em '$emulatorPath'." -ForegroundColor Yellow
Write-Host "Verifique o caminho do SDK do Android no script." -ForegroundColor Yellow
Start-Sleep -Seconds 2
return
}
$script:availableEmulators = & "$emulatorPath\emulator.exe" -list-avds | Where-Object { $_.Trim() -ne "" }
if ($availableEmulators.Count -eq 0) { Write-Host "AVISO: Nenhum emulador (AVD) foi encontrado." -ForegroundColor Yellow$script:emulatorName = ""
}
elseif ($availableEmulators.Count -eq 1) {$script:emulatorName = $availableEmulators[0] Write-Host "Emulador '$emulatorName' selecionado automaticamente." -ForegroundColor Green
}
else {
$script:emulatorName = $availableEmulators[0]
Write-Host "Múltiplos emuladores encontrados. '$emulatorName' foi selecionado como padrão." -ForegroundColor Green
Write-Host "Use a opção 'S' no menu para selecionar outro."
}
Start-Sleep -Seconds 2
}
function Select-Emulator {
Clear-Host
Write-Host "--- SELECIONAR EMULADOR ANDROID ---" -ForegroundColor Yellow
if ($availableEmulators.Count -eq 0) {
Read-Host "Nenhum emulador foi detectado. Pressione Enter"
return
}
Write-Host "`nEmuladores disponíveis:"
for ($i = 0; $i -lt $availableEmulators.Count; $i++) {
$indicator = "" if ($availableEmulators[$i] -eq $emulatorName) { $indicator = " [SELECIONADO]" } Write-Host "$($i + 1). $($availableEmulators[$i])$indicator"
}
$choice = Read-Host "`nDigite o número do emulador que deseja usar e pressione Enter (ou Enter para cancelar)" if ([string]::IsNullOrWhiteSpace($choice)) { return }
if ($choice -match '^\d+$' -and [int]$choice -ge 1 -and [int]$choice -le $availableEmulators.Count) {$script:emulatorName = $availableEmulators[[int]$choice - 1]
Write-Host "Emulador '$emulatorName' selecionado." -ForegroundColor Green
}
else {
Write-Host "Seleção inválida. Nenhuma alteração foi feita." -ForegroundColor Red
}
Start-Sleep -Seconds 2
}
#==============================================================================
# --- FUNÇÕES AUXILIARES ---
#==============================================================================
function Get-ServiceStatus {
param([string]$Service) switch ($Service) {
'api' { if (Get-NetTCPConnection -LocalPort 8080 -State Listen -ErrorAction SilentlyContinue) { "RUNNING" } else { "STOPPED" } }
'web' { if (Get-NetTCPConnection -LocalPort 4200 -State Listen -ErrorAction SilentlyContinue) { "RUNNING" } else { "STOPPED" } }
'desktop' { if (Get-Process | Where-Object { $_.MainWindowTitle -like "*$desktopWindowTitle*" }) { "RUNNING" } else { "STOPPED" } }
'android' {
$running = & "$platformToolsPath\adb.exe" shell ps 2>$null | Select-String $androidPackage
if ($running) { "RUNNING" } else { "STOPPED" } } 'emulator' {$devices = & "$platformToolsPath\adb.exe" devices 2>$null | Select-String "device$" if ($devices) { "RUNNING" } else { "STOPPED" }
}
}
}
function Wait-ForAdbDevice {
$timeout = 90 if ((Get-ServiceStatus 'emulator') -eq "RUNNING") { return$true }
Write-Host "Aguardando o emulador/dispositivo ficar online..." -ForegroundColor Cyan -NoNewline
$elapsed = 0 while ($elapsed -lt $timeout) { if ((Get-ServiceStatus 'emulator') -eq "RUNNING") { Write-Host "`nDispositivo detectado." -ForegroundColor Green Start-Sleep -Seconds 1 return$true
}
Write-Host "." -NoNewline
Start-Sleep -Seconds 2
$elapsed += 2 } Write-Host "`nTempo esgotado!" -ForegroundColor Red return$false
}
function Confirm-BuildArtifact {
param([string]$ArtifactPath, [string]$ProjectPath)
if (-not (Test-Path $ArtifactPath)) {$choice = Read-Host "Artefato de build não encontrado em '$ArtifactPath'. Deseja construir agora? (s/n)" if ($choice -eq "s") {
Push-Location $ProjectPath & .\mvnw.cmd clean package$exitCode = $LASTEXITCODE Pop-Location if ($exitCode -ne 0) {
Write-Host "ERRO DE BUILD." -ForegroundColor Red
Start-Sleep -Seconds 2
return $false } } else { Write-Host "Início cancelado." -ForegroundColor Red Start-Sleep -Seconds 2 return$false
}
}
return $true
}
#==============================================================================
# --- FUNÇÕES DE GERENCIAMENTO ---
#==============================================================================
function Start-AppService {
param([string]$Service, [string]$ColdBoot)
if ($Service -in @('web', 'desktop', 'android') -and (Get-ServiceStatus 'api') -eq "STOPPED") {$confirm = Read-Host "AVISO: A API está parada. Deseja iniciá-la primeiro? (s/n)"
if ($confirm -eq "s") { if (-not (Start-AppService 'api')) { Write-Host "Falha ao iniciar API." -ForegroundColor Red Start-Sleep -Seconds 2 return$false
}
}
}
Write-Host "`nTentando iniciar serviço: $Service..." -ForegroundColor Yellow switch ($Service) {
'api' {
if (-not (Confirm-BuildArtifact $apiJar $apiPath)) { return $false } Start-Process powershell -ArgumentList "-NoExit", "-Command", "cd '$apiPath'; java -jar '$apiJar'" } 'web' { Start-Process powershell -ArgumentList "-NoExit", "-Command", "cd '$webPath'; ng serve --open"
}
'desktop' {
if (-not (Confirm-BuildArtifact $desktopJar $desktopPath)) { return $false } Start-Process powershell -ArgumentList "-NoExit", "-Command", "cd '$desktopPath'; java -jar '$desktopJar'" } 'android' { if (-not (Wait-ForAdbDevice)) { Write-Host "Nenhum emulador/dispositivo detectado." -ForegroundColor Red Start-Sleep -Seconds 2 return$false
}
Write-Host "Criando túnel de rede (adb reverse)..." -ForegroundColor Cyan
& "$platformToolsPath\adb.exe" reverse tcp:8080 tcp:8080 Write-Host "Iniciando App Mobile..." & "$platformToolsPath\adb.exe" shell am start -n "$androidPackage/$androidPackage.MainActivity"
}
'emulator' {
if ([string]::IsNullOrWhiteSpace($emulatorName)) { Write-Host "Nenhum emulador está selecionado." -ForegroundColor Yellow Select-Emulator if ([string]::IsNullOrWhiteSpace($emulatorName)) {
Read-Host "Operação cancelada. Pressione Enter"
return $false } } if ((Get-ServiceStatus 'emulator') -eq "RUNNING") { Write-Host "Emulador já parece estar rodando." -ForegroundColor Green return$true
}
$emuArgs = @("-avd", $emulatorName)
if ($ColdBoot -eq "-ColdBoot") {$emuArgs += "-no-snapshot-load"
Write-Host "Iniciando emulador em modo Cold Boot..." -ForegroundColor Yellow
}
Start-Process -FilePath "$emulatorPath\emulator.exe" -ArgumentList $emuArgs -WindowStyle Hidden
if (-not (Wait-ForAdbDevice)) { return $false } } } return$true
}
function Stop-AppService {
param([string]$Service) Write-Host "`nParando serviço:$Service..." -ForegroundColor Yellow
switch ($Service) { 'api' { Get-NetTCPConnection -LocalPort 8080 -State Listen -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess -Unique | ForEach-Object { Stop-Process -Id$_ -Force -ErrorAction SilentlyContinue }
}
'web' {
Get-NetTCPConnection -LocalPort 4200 -State Listen -ErrorAction SilentlyContinue |
Select-Object -ExpandProperty OwningProcess -Unique |
ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue } } 'desktop' { Get-Process | Where-Object {$_.MainWindowTitle -like "*$desktopWindowTitle*" } | Stop-Process -Force -ErrorAction SilentlyContinue } 'android' { & "$platformToolsPath\adb.exe" shell am force-stop $androidPackage } 'emulator' { & "$platformToolsPath\adb.exe" emu kill }
}
Write-Host "Comando de parada enviado." -ForegroundColor Green
Start-Sleep -Seconds 1
}
function Clear-ProjectCaches {
Clear-Host
Write-Host "--- LIMPANDO CACHES E BUILDS ---" -ForegroundColor Yellow
Write-Host "`nLimpando API..." -ForegroundColor Cyan
Push-Location $apiPath; & .\mvnw.cmd clean; Pop-Location Write-Host "`nLimpando Desktop..." -ForegroundColor Cyan Push-Location$desktopPath; & .\mvnw.cmd clean; Pop-Location
Write-Host "`nLimpando Web..." -ForegroundColor Cyan
Remove-Item -Recurse -Force "$webPath\.angular", "$webPath\dist" -ErrorAction SilentlyContinue
Write-Host "`n--- LIMPEZA CONCLUÍDA ---" -ForegroundColor Green
Read-Host "Pressione Enter"
}
function Invoke-AdbTool {
param([string]$Tool) if (-not (Wait-ForAdbDevice)) { Read-Host "Operação ADB cancelada. Pressione Enter" return } Clear-Host Write-Host "--- Ferramenta Mobile (ADB):$Tool ---" -ForegroundColor Yellow
switch ($Tool) { 'reset' { & "$platformToolsPath\adb.exe" kill-server; & "$platformToolsPath\adb.exe" start-server } 'devices' { & "$platformToolsPath\adb.exe" devices }
'logcat' {
Start-Process powershell -ArgumentList "-NoExit", "-Command", "& '$platformToolsPath\adb.exe' logcat '*:S' '$androidPackage:V'"
return
}
'reverse' {
& "$platformToolsPath\adb.exe" reverse tcp:8080 tcp:8080 Write-Host "Verificando túneis:" & "$platformToolsPath\adb.exe" reverse --list
}
}
Read-Host "`nPressione Enter para voltar ao menu"
}
#==============================================================================
# --- INTERFACE DO USUÁRIO (MENU) ---
#==============================================================================
function Show-Menu {
Clear-Host
Write-Host "=================================================" -ForegroundColor Cyan
Write-Host " PAINEL DE CONTROLE - PROJETO TO-DO LIST " -ForegroundColor White
Write-Host "=================================================" -ForegroundColor Cyan
$emulatorDisplayName = if ($emulatorName) { $emulatorName } else { "Nenhum Selecionado" }$statuses = [ordered]@{
"Emulador ($emulatorDisplayName)" = Get-ServiceStatus 'emulator'
"API Backend" = Get-ServiceStatus 'api'
"Frontend Web" = Get-ServiceStatus 'web'
"App Desktop" = Get-ServiceStatus 'desktop'
"App Mobile" = if ((Get-ServiceStatus 'emulator') -eq "RUNNING") { Get-ServiceStatus 'android' } else { "OFFLINE" }
}
Write-Host "`nSTATUS ATUAL:" -ForegroundColor White
foreach ($key in $statuses.Keys) {
$color = if ($statuses[$key] -eq "RUNNING") { "Green" } else { "Red" } Write-Host (" {0,-30} " -f$key) -NoNewline
Write-Host $statuses[$key] -ForegroundColor $color
}
Write-Host "`n--- OPÇÕES ---" -ForegroundColor Yellow
Write-Host " GERAL SERVIÇOS INDIVIDUAIS"
Write-Host " 9) Iniciar TUDO 1) Iniciar API 5) Iniciar Desktop"
Write-Host " 10) Parar TUDO 2) Parar API 6) Parar Desktop"
Write-Host " L) Limpar Caches 3) Iniciar Web 7) Iniciar App Mobile"
Write-Host " 4) Parar Web 8) Parar App Mobile"
Write-Host "-----------------------------------------------------------------"
Write-Host " FERRAMENTAS MOBILE (ANDROID) NAVEGAÇÃO"
Write-Host " A) Iniciar Emulador D) Resetar Servidor ADB R) Atualizar Status"
Write-Host " B) Parar Emulador E) Listar Dispositivos Q) Sair"
Write-Host " H) Ligar (Cold Boot) F) Ver Logs (logcat)"
Write-Host " S) Selecionar Emulador G) Criar Túnel de Rede"
Write-Host ""
}
#==============================================================================
# --- LÓGICA PRINCIPAL (LOOP DO MENU) ---
#==============================================================================
Test-Dependencies
Initialize-EmulatorSelection
while ($true) { Show-Menu$choice = (Read-Host "Digite sua opção e pressione Enter").ToLower()
switch ($choice) { '1' { Start-AppService 'api' | Out-Null } '2' { Stop-AppService 'api' } '3' { Start-AppService 'web' | Out-Null } '4' { Stop-AppService 'web' } '5' { Start-AppService 'desktop' | Out-Null } '6' { Stop-AppService 'desktop' } '7' { Start-AppService 'android' | Out-Null } '8' { Stop-AppService 'android' } '9' { if (-not (Start-AppService 'emulator')) { Read-Host "Falha ao iniciar Emulador"; continue } if (-not (Start-AppService 'api')) { Read-Host "Falha ao iniciar API"; continue } Start-AppService 'web' | Out-Null Start-AppService 'desktop' | Out-Null Start-AppService 'android' | Out-Null Read-Host "`n--- SEQUÊNCIA CONCLUÍDA ---`nPressione Enter" } '10' { Stop-AppService 'android'; Stop-AppService 'desktop'; Stop-AppService 'web'; Stop-AppService 'api' if ((Get-ServiceStatus 'emulator') -eq "RUNNING") {$confirm = Read-Host "Deseja parar o Emulador também? (s/n)"
if ($confirm -eq "s") { Stop-AppService 'emulator' } } } 'a' { Start-AppService 'emulator' | Out-Null } 'b' { Stop-AppService 'emulator' } 'h' { Start-AppService 'emulator' '-ColdBoot' | Out-Null } 's' { Select-Emulator } 'c' { Start-Process$webUrl }
'd' { Invoke-AdbTool 'reset' }
'e' { Invoke-AdbTool 'devices' }
'f' { Invoke-AdbTool 'logcat' }
'g' { Invoke-AdbTool 'reverse' }
'l' { Clear-ProjectCaches }
'r' { }
'q' { break }
default { Write-Host "Opção inválida!" -ForegroundColor Red; Start-Sleep -Seconds 2 }
}
}
.\listadetarefas-painel.ps1