scripts/internal/host-runtime-inventory.ps1
|
# Per-host Crew-runtime install inventory — registry-driven iterator (Phase C refactor) # # Original per-host Test-<Host>RuntimeInstalled implementations moved to # hosts/<kind>/handlers.ps1 (Phase B). The original per-host wrapper functions # in this file were removed in Phase C because they collided with the handler # function names in the same scope (causing infinite recursion). Callers that # need per-host detection use Invoke-HostHandler -ContractFunction TestRuntimeInstalled. # # Only the aggregate iterator Get-SpecrewHostRuntimeInventory remains here as # a host-neutral public API. # # To add detection for a new host, implement Test-<Kind>RuntimeInstalled in # the host's handlers.ps1 — this iterator picks it up automatically via the registry. Set-StrictMode -Version Latest $script:RegistryPath = Join-Path (Split-Path -Parent $PSScriptRoot) 'hosts\_registry.ps1' if (-not (Test-Path -LiteralPath $script:RegistryPath -PathType Leaf)) { # Module-mode lookup: when running from installed Specrew module, hosts/ is a sibling of scripts/ $script:RegistryPath = Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) 'hosts\_registry.ps1' } if (-not (Test-Path -LiteralPath $script:RegistryPath -PathType Leaf)) { throw "Host registry not found. Searched: $script:RegistryPath" } . $script:RegistryPath function Get-SpecrewHostRuntimeInventory { <# .SYNOPSIS Aggregate per-host Crew-runtime install state for this project — host-neutral iterator. Iterates the registry; for each registered host, dispatches its TestRuntimeInstalled. Returns an ordered hashtable keyed by host kind with @{ installed = $bool; path = $string-or-null }. No host names hardcoded — adding a new host (hosts/<kind>/) makes it appear here automatically. #> param([Parameter(Mandatory = $true)][string]$ProjectPath) $result = [ordered]@{} foreach ($kind in Get-RegisteredHostKinds) { $installed = [bool](Invoke-HostHandler -Kind $kind -ContractFunction TestRuntimeInstalled -Arguments @{ ProjectPath = $ProjectPath }) # Path for the "installed" case derives from the manifest's AgentDir field. # Open-Closed: every supported host declares AgentDir; adding a new host adds # one manifest line, no edits to this iterator. $path = $null if ($installed) { $manifest = Get-HostManifest -Kind $kind if ($manifest.ContainsKey('AgentDir') -and -not [string]::IsNullOrWhiteSpace([string]$manifest.AgentDir)) { $path = (Join-Path $ProjectPath (([string]$manifest.AgentDir) -replace '/', [System.IO.Path]::DirectorySeparatorChar).TrimEnd([System.IO.Path]::DirectorySeparatorChar)) } } $result[$kind] = @{ installed = $installed; path = $path } } return $result } |