Sharpdown.Build.ps1

Set-StrictMode -Version Latest
#### <h1 style="color: #DCA657;">🔨 Sharpdown.Build</h1>
####
#### > InvokeBuild tasks for dependency installation, tests, analyzer output, and generated docs.
####
#### ---
####
#### | Task | Purpose |
#### | --- | --- |
#### | `install_modules` | Install manifest-declared module dependencies for the current user. |
#### | `test_pester` | Run the Pester suite and write result artifacts under `Generated`. |
#### | `test_ps_script_analyzer` | Run PSScriptAnalyzer and write its report under `Generated`. |
#### | `build_sharpdown` | Regenerate the generated Markdown docs from PowerShell source. |
#### | `.` | Run the full build chain. |
####
#### ---

$script:Generated = Join-Path -Path "$($PSScriptRoot)" -ChildPath "Generated"
$script:SdownPsd1File = "Sharpdown.psd1"

#### <h2 style="color: #DCA657;">install_modules</h2>
####
#### Installs each module listed in the manifest's `RequiredModules` field.
####
#### <b style="color: #D2A8FF;">Inputs</b>
#### - `Sharpdown.psd1`
#### - *The build reads `RequiredModules` from the module manifest.*
####
#### <b style="color: #369FFF;">Outputs</b>
#### - Installed modules in the current user's module scope.
Add-BuildTask install_modules {
    $root = $PSScriptRoot
    $dataFilePath = Join-Path -Path $root -ChildPath "$($script:SdownPsd1File)"
    $dataFile = Import-PowerShellDataFile -Path $dataFilePath

    if($dataFile.RequiredModules.Length -gt 0) {
        $dataFile.RequiredModules | ForEach-Object {
            Install-Module -Name $_.ModuleName -RequiredVersion $_.RequiredVersion -Verbose -Scope CurrentUser
        }
    }
}

#### ---
#### <h2 style="color: #DCA657;">test_pester</h2>
####
#### Runs the Pester 5 suite and fails the build on any failing test.
####
#### <b style="color: #D2A8FF;">Inputs</b>
#### - `Tests`
#### - *The Pester test tree.*
#### - `Sharpdown.psm1`
#### - *The module file measured by code coverage.*
####
#### <b style="color: #369FFF;">Outputs</b>
#### - `Generated/PesterTests.xml`
#### - *Pester test result artifact.*
#### - `Generated/PesterCodeCoverage.xml`
#### - *Code coverage artifact for the module.*
Add-BuildTask test_pester {
    Import-Module Pester
    [void](New-Item -Path $script:Generated -ItemType Directory -Force)

    $configuration = [PesterConfiguration]::Default
    $configuration.Run.Path = Join-Path -Path $PSScriptRoot -ChildPath 'Tests'
    $configuration.Run.PassThru = $true
    $configuration.TestResult.Enabled = $true
    $configuration.TestResult.OutputPath = Join-Path -Path $script:Generated -ChildPath 'PesterTests.xml'
    $configuration.CodeCoverage.Enabled = $true
    $configuration.CodeCoverage.OutputPath = Join-Path -Path $script:Generated -ChildPath 'PesterCodeCoverage.xml'
    $configuration.CodeCoverage.Path = Join-Path -Path $PSScriptRoot -ChildPath 'Sharpdown.psm1'
    $configuration.Output.Verbosity = 'Detailed'

    $PSStyle.OutputRendering = 'PlainText'
    $result = Invoke-Pester -Configuration $configuration
    $PSStyle.OutputRendering = 'Ansi'

    if ($result.FailedCount -gt 0) {
        throw "Pester failed: $($result.FailedCount) of $($result.TotalCount) tests did not pass."
    }
}

#### ---
#### <h2 style="color: #DCA657;">test_ps_script_analyzer</h2>
####
#### Runs PSScriptAnalyzer across the repository and writes a report.
####
#### <b style="color: #D2A8FF;">Inputs</b>
#### - Repository PowerShell files.
#### - *The analyzer walks from the repository root.*
####
#### <b style="color: #369FFF;">Outputs</b>
#### - `Generated/ScriptAnalyzer.txt`
#### - *Analyzer report with the default rules and suppressed diagnostics included.*
Add-BuildTask test_ps_script_analyzer {
    [void](New-Item -Path "$($script:Generated)" -ItemType Directory -ErrorAction SilentlyContinue)
    Invoke-ScriptAnalyzer -Path .\ -IncludeDefaultRules -IncludeSuppressed -ReportSummary |
        Out-File -FilePath (Join-Path -Path "$($script:Generated)" -ChildPath "ScriptAnalyzer.txt")
}
#### ---
#### <h2 style="color: #DCA657;">build_sharpdown</h2>
####
#### Regenerates the `Docs` tree from every PowerShell source file.
####
#### <b style="color: #D2A8FF;">Inputs</b>
#### - Repository PowerShell files.
#### - *`ConvertTo-SharpDown` walks the repository in PowerShell mode.*
####
#### <b style="color: #369FFF;">Outputs</b>
#### - `Docs`
#### - *Generated Markdown mirror of the documented PowerShell source.*
Add-BuildTask build_sharpdown {
    Import-Module (Join-Path -Path $PSScriptRoot -ChildPath $script:SdownPsd1File) -Force
    $docsRoot = Join-Path -Path $PSScriptRoot -ChildPath 'Docs'
    ConvertTo-SharpDown -Language PowerShell -Path $PSScriptRoot -OutPath $docsRoot -Recurse
}

#### ---
#### <h2 style="color: #DCA657;">default</h2>
####
#### Runs the full build chain in dependency, test, analyzer, and docs order.
####
#### <b style="color: #D2A8FF;">Tasks</b>
#### - `install_modules`
#### - `test_pester`
#### - `test_ps_script_analyzer`
#### - `build_sharpdown`
Add-BuildTask . install_modules, test_pester, test_ps_script_analyzer, build_sharpdown