build.ps1

<#
.SYNOPSIS
    Build script for WinPath-Clean module.
     
.DESCRIPTION
    Builds, tests, and packages the WinPath-Clean PowerShell module.
     
.PARAMETER Task
    The build task to run: Build, Test, Package, Publish, or Clean.
     
.PARAMETER Version
    Version number for release builds.
     
.EXAMPLE
    .\build.ps1 -Task Test
     
.EXAMPLE
    .\build.ps1 -Task Package -Version "1.0.0"
#>

[CmdletBinding()]
param(
    [ValidateSet('Build', 'Test', 'Package', 'Publish', 'Clean', 'All')]
    [string]$Task = 'Build',
    
    [string]$Version,
    
    [switch]$Release
)

$ErrorActionPreference = 'Stop'
$ModuleName = 'WinPath-Clean'
$OutputDir = Join-Path $PSScriptRoot 'out'
$PublishDir = Join-Path $PSScriptRoot 'publish'

function Invoke-Build {
    Write-Host "🔨 Building $ModuleName..." -ForegroundColor Cyan
    
    # Validate module
    $manifest = Test-ModuleManifest -Path "$PSScriptRoot\$ModuleName.psd1"
    Write-Host " Module version: $($manifest.Version)" -ForegroundColor Gray
    Write-Host " PowerShell version required: $($manifest.PowerShellVersion)" -ForegroundColor Gray
    
    # Create output directory
    if (-not (Test-Path $OutputDir)) {
        New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
    }
    
    # Copy module files
    $moduleOutput = Join-Path $OutputDir $ModuleName
    if (Test-Path $moduleOutput) {
        Remove-Item $moduleOutput -Recurse -Force
    }
    New-Item -ItemType Directory -Path $moduleOutput -Force | Out-Null
    
    Copy-Item "$PSScriptRoot\$ModuleName.psd1" $moduleOutput
    Copy-Item "$PSScriptRoot\$ModuleName.psm1" $moduleOutput
    Copy-Item "$PSScriptRoot\Public" $moduleOutput -Recurse
    Copy-Item "$PSScriptRoot\Private" $moduleOutput -Recurse
    Copy-Item "$PSScriptRoot\README.md" $moduleOutput
    Copy-Item "$PSScriptRoot\LICENSE" $moduleOutput
    Copy-Item "$PSScriptRoot\CHANGELOG.md" $moduleOutput
    
    Write-Host "✓ Build complete: $moduleOutput" -ForegroundColor Green
}

function Invoke-Test {
    Write-Host "🧪 Running tests..." -ForegroundColor Cyan
    
    # Check for Pester
    if (-not (Get-Module -ListAvailable -Name Pester)) {
        Write-Host " Installing Pester..." -ForegroundColor Gray
        Install-Module Pester -Force -Scope CurrentUser
    }
    
    Import-Module Pester -Force
    
    $testResults = Invoke-Pester -Path "$PSScriptRoot\Tests" -PassThru -Output Detailed
    
    if ($testResults.FailedCount -gt 0) {
        throw "Tests failed: $($testResults.FailedCount) failures"
    }
    
    Write-Host "✓ All tests passed!" -ForegroundColor Green
}

function Invoke-Package {
    Write-Host "📦 Packaging $ModuleName..." -ForegroundColor Cyan
    
    if (-not $Version) {
        $manifest = Test-ModuleManifest -Path "$PSScriptRoot\$ModuleName.psd1"
        $Version = $manifest.Version.ToString()
    }
    
    # Create publish directory
    if (-not (Test-Path $PublishDir)) {
        New-Item -ItemType Directory -Path $PublishDir -Force | Out-Null
    }
    
    $moduleOutput = Join-Path $OutputDir $ModuleName
    if (-not (Test-Path $moduleOutput)) {
        Invoke-Build
    }
    
    # Create ZIP package
    $zipPath = Join-Path $PublishDir "$ModuleName-$Version.zip"
    Compress-Archive -Path $moduleOutput -DestinationPath $zipPath -Force
    
    Write-Host "✓ Package created: $zipPath" -ForegroundColor Green
    
    # Create NuGet package (for PSGallery)
    Write-Host " Creating NuGet package..." -ForegroundColor Gray
    
    return $zipPath
}

function Invoke-Publish {
    Write-Host "🚀 Publishing $ModuleName..." -ForegroundColor Cyan
    
    $apiKey = $env:PSGALLERY_API_KEY
    if (-not $apiKey) {
        throw "PSGALLERY_API_KEY environment variable not set"
    }
    
    Invoke-Build
    Invoke-Test
    
    $moduleOutput = Join-Path $OutputDir $ModuleName
    
    Write-Host " Publishing to PowerShell Gallery..." -ForegroundColor Gray
    Publish-Module -Path $moduleOutput -NuGetApiKey $apiKey -Verbose
    
    Write-Host "✓ Published to PowerShell Gallery!" -ForegroundColor Green
}

function Invoke-Clean {
    Write-Host "🧹 Cleaning..." -ForegroundColor Cyan
    
    if (Test-Path $OutputDir) {
        Remove-Item $OutputDir -Recurse -Force
    }
    if (Test-Path $PublishDir) {
        Remove-Item $PublishDir -Recurse -Force
    }
    
    Write-Host "✓ Clean complete" -ForegroundColor Green
}

# Main execution
switch ($Task) {
    'Build' { Invoke-Build }
    'Test' { Invoke-Test }
    'Package' { 
        Invoke-Build
        Invoke-Package 
    }
    'Publish' { Invoke-Publish }
    'Clean' { Invoke-Clean }
    'All' {
        Invoke-Clean
        Invoke-Build
        Invoke-Test
        Invoke-Package
    }
}