Private/IssueHelpers.ps1
|
function Read-IssueFile { <# .SYNOPSIS Lee y parsea un archivo de issue con formato frontmatter YAML. .DESCRIPTION Extrae el título, labels y cuerpo de un archivo markdown con frontmatter YAML. Valida la estructura y campos requeridos. .PARAMETER Path Ruta al archivo de issue. .OUTPUTS PSCustomObject con propiedades Title, Labels y Body. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Path ) $ErrorActionPreference = 'Stop' try { # Leer contenido del archivo $content = Get-Content -Path $Path -Raw -Encoding UTF8 if ([string]::IsNullOrWhiteSpace($content)) { throw "El archivo está vacío" } # Verificar formato frontmatter if (-not $content.StartsWith('---')) { Show-IssueFormatHelp throw "El archivo debe comenzar con frontmatter YAML (---)" } # Extraer frontmatter y body $pattern = '(?s)^---\s*\r?\n(.*?)\r?\n---\s*\r?\n(.*)$' $match = [regex]::Match($content, $pattern) if (-not $match.Success) { Show-IssueFormatHelp throw "Formato de frontmatter inválido. Debe tener --- al inicio y fin del frontmatter." } $frontmatter = $match.Groups[1].Value $body = $match.Groups[2].Value.Trim() # Parsear YAML manualmente (simple key: value) $title = $null $labels = $null foreach ($line in $frontmatter -split '\r?\n') { $line = $line.Trim() if ($line -match '^title:\s*(.+)$') { $title = $matches[1].Trim() } elseif ($line -match '^labels:\s*(.+)$') { $labels = $matches[1].Trim() } } # Validar campos requeridos if ([string]::IsNullOrWhiteSpace($title)) { Show-IssueFormatHelp throw "El campo 'title' es requerido en el frontmatter" } if ([string]::IsNullOrWhiteSpace($body)) { Write-Warning "El cuerpo de la issue está vacío" } # Retornar objeto parseado [PSCustomObject]@{ Title = $title Labels = $labels Body = $body } } catch { throw } } function Show-IssueFormatHelp { <# .SYNOPSIS Muestra la estructura esperada para un archivo de issue. #> [CmdletBinding()] param() $template = @" ╔════════════════════════════════════════════════════════════════╗ ║ FORMATO ESPERADO PARA ARCHIVO DE ISSUE ║ ╚════════════════════════════════════════════════════════════════╝ --- title: 🐛 [Bug] Título descriptivo del problema labels: bug,enhancement,documentation --- # Descripción Descripción detallada del problema o feature request. ## Contexto adicional Información adicional, screenshots, logs, etc. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 📝 CAMPOS FRONTMATTER: • title: (REQUERIDO) Título de la issue • labels: (OPCIONAL) Labels separados por coma 🏷️ LABELS DISPONIBLES: • bug, documentation, duplicate, enhancement • good first issue, help wanted, invalid • question, wontfix 💡 TIP: Usa emojis como 🐛 (bug), ✨ (feature), 📚 (docs) "@ Write-Host $template -ForegroundColor Cyan } function Test-GitHubCLI { <# .SYNOPSIS Valida que GitHub CLI esté instalado y autenticado. .DESCRIPTION Verifica la instalación de gh CLI y el estado de autenticación. .OUTPUTS Boolean indicando si gh CLI está listo para usar. #> [CmdletBinding()] param() $ErrorActionPreference = 'Stop' # Verificar instalación de gh $ghCommand = Get-Command 'gh' -ErrorAction SilentlyContinue if (-not $ghCommand) { Write-Host "❌ GitHub CLI (gh) no está instalado" -ForegroundColor Red Write-Host "" Write-Host "📥 Instalar GitHub CLI:" -ForegroundColor Yellow Write-Host " winget install GitHub.cli" -ForegroundColor Cyan Write-Host " https://cli.github.com/" -ForegroundColor Cyan return $false } # Verificar autenticación try { $null = gh auth status 2>&1 if ($LASTEXITCODE -ne 0) { Write-Host "❌ No estás autenticado con GitHub CLI" -ForegroundColor Red Write-Host "" Write-Host "🔐 Autenticarse con GitHub:" -ForegroundColor Yellow Write-Host " gh auth login" -ForegroundColor Cyan return $false } } catch { Write-Host "❌ Error al verificar autenticación: $_" -ForegroundColor Red return $false } return $true } function Test-GitRepository { <# .SYNOPSIS Verifica que estamos en un repositorio Git válido. .OUTPUTS Boolean indicando si estamos en un repositorio Git. #> [CmdletBinding()] param() $ErrorActionPreference = 'Stop' try { $null = git rev-parse --git-dir 2>&1 if ($LASTEXITCODE -ne 0) { Write-Host "❌ No estás en un repositorio Git" -ForegroundColor Red Write-Host "" Write-Host "💡 Ejecuta este comando dentro de un repositorio Git" -ForegroundColor Yellow return $false } return $true } catch { Write-Host "❌ Git no está instalado o no se puede ejecutar" -ForegroundColor Red return $false } } function Format-Labels { <# .SYNOPSIS Formatea y valida labels para GitHub. .PARAMETER Labels String con labels separados por coma. .OUTPUTS String con labels formateados. #> [CmdletBinding()] param( [Parameter(Mandatory)] [AllowEmptyString()] [string]$Labels ) if ([string]::IsNullOrWhiteSpace($Labels)) { return $null } # Remover espacios extras y normalizar $labelArray = $Labels -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' } if ($labelArray.Count -eq 0) { return $null } # Retornar labels unidos por coma return ($labelArray -join ',') } |