build.ps1

#Requires -Version 5.1
#Requires -Modules @{ ModuleName='Pester'; ModuleVersion='5.0.0' }
#Requires -Modules PSScriptAnalyzer

<#
.SYNOPSIS
    Build script for Export-ModuleInfoForLLM module
.DESCRIPTION
    Handles testing, analysis, building, and packaging of the module
.PARAMETER Task
    The build task to execute
#>


[CmdletBinding()]
param(
    [Parameter()]
    [ValidateSet('Test', 'Analyze', 'Build', 'Package', 'Clean', 'All')]
    [string]$Task = 'Test',

    [Parameter()]
    [switch]$SkipTests,

    [Parameter()]
    [switch]$CodeCoverage
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

# Module information
$moduleName = 'Export-ModuleInfoForLLM'
$moduleRoot = $PSScriptRoot
$outputDir = Join-Path $moduleRoot 'build'
$testResultsFile = Join-Path $outputDir 'TestResults.xml'

# Tasks
function Invoke-Clean {
    Write-Host "Cleaning build artifacts..." -ForegroundColor Cyan
    if (Test-Path $outputDir) {
        Remove-Item $outputDir -Recurse -Force
    }
    New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
}

function Invoke-Analyze {
    Write-Host "Running PSScriptAnalyzer..." -ForegroundColor Cyan
    $analyzerParams = @{
        Path = $moduleRoot
        Recurse = $true
        Settings = 'PSGallery'
        ExcludeRule = @('PSUseDeclaredVarsMoreThanAssignments')
    }

    $results = Invoke-ScriptAnalyzer @analyzerParams

    if ($results) {
        $results | Format-Table -AutoSize
        throw "PSScriptAnalyzer found $($results.Count) issues"
    }

    Write-Host "✓ PSScriptAnalyzer passed" -ForegroundColor Green
}

function Invoke-Test {
    Write-Host "Running Pester tests..." -ForegroundColor Cyan

    $pesterParams = @{
        Path = Join-Path $moduleRoot 'Tests'
        OutputFile = $testResultsFile
        OutputFormat = 'NUnitXml'
        PassThru = $true
    }

    if ($CodeCoverage) {
        $pesterParams.CodeCoverage = @(
            Join-Path $moduleRoot 'Public\*.ps1'
            Join-Path $moduleRoot 'Private\*.ps1'
        )
        $pesterParams.CodeCoverageOutputFile = Join-Path $outputDir 'coverage.xml'
    }

    $results = Invoke-Pester @pesterParams

    if ($results.FailedCount -gt 0) {
        throw "Pester tests failed: $($results.FailedCount) test(s) failed"
    }

    Write-Host "✓ All tests passed" -ForegroundColor Green

    if ($CodeCoverage) {
        $coverage = [Math]::Round(($results.CodeCoverage.NumberOfCommandsExecuted / $results.CodeCoverage.NumberOfCommandsAnalyzed) * 100, 2)
        Write-Host "Code Coverage: $coverage%" -ForegroundColor Yellow

        if ($coverage -lt 80) {
            Write-Warning "Code coverage is below 80% threshold"
        }
    }
}

function Invoke-Build {
    Write-Host "Building module..." -ForegroundColor Cyan

    # Update module manifest version if needed
    $manifest = Import-PowerShellDataFile (Join-Path $moduleRoot "$moduleName.psd1")
    Write-Host "Current version: $($manifest.ModuleVersion)" -ForegroundColor Gray

    # Compile module if needed (for large modules)
    # This is where you could combine files, update help, etc.

    Write-Host "✓ Build completed" -ForegroundColor Green
}

function Invoke-Package {
    Write-Host "Creating package..." -ForegroundColor Cyan

    $packageDir = Join-Path $outputDir $moduleName

    # Copy module files
    Copy-Item $moduleRoot -Destination $packageDir -Recurse -Exclude @(
        '.git*',
        'build',
        'TestOutput',
        '*.Tests.ps1',
        '.vscode'
    )

    # Create zip package
    $zipPath = Join-Path $outputDir "$moduleName.zip"
    Compress-Archive -Path $packageDir -DestinationPath $zipPath -Force

    Write-Host "✓ Package created: $zipPath" -ForegroundColor Green
}

# Main execution
try {
    switch ($Task) {
        'Clean' {
            Invoke-Clean
        }
        'Analyze' {
            Invoke-Analyze
        }
        'Test' {
            if (-not $SkipTests) {
                Invoke-Test
            }
        }
        'Build' {
            Invoke-Clean
            Invoke-Analyze
            if (-not $SkipTests) {
                Invoke-Test
            }
            Invoke-Build
        }
        'Package' {
            Invoke-Clean
            Invoke-Analyze
            if (-not $SkipTests) {
                Invoke-Test
            }
            Invoke-Build
            Invoke-Package
        }
        'All' {
            Invoke-Clean
            Invoke-Analyze
            Invoke-Test
            Invoke-Build
            Invoke-Package
        }
    }
}
catch {
    Write-Error $_
    exit 1
}