src/pipeline/Get-ScoutCategoryCoverage.ps1
|
#Requires -Version 7.0 Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' <# .SYNOPSIS Per-category collector coverage counts, derived from manifests/collectors/ (AB#7102). .DESCRIPTION The wizard's category checklist (AB#7101) used to show eighteen bare category names with no indication of how much any of them actually collects. Any figure typed next to a category name -- "Analytics (6/19)" -- rots the moment a collector is added, retired, or breaks its schema, exactly the way the old hand-maintained `docs/reference/arm-modules.md` rotted before `scripts/Build-ArmModuleCatalog.ps1` started generating it (AB#6741). This function is that same read, exposed as a callable instead of an inline build-script block, so the wizard (a running module) and the docs generator (a standalone script) can both derive their counts from one manifest walk. It reuses `Get-ScoutCollectorDefinition` -- the same schema-validating reader `scripts/Build-ArmModuleCatalog.ps1` already uses -- rather than re-parsing `.psd1` files with a second, independent implementation. Per category: Published — every `.psd1` file under the category's manifest directory. A definition that exists is published; whether it also *works* is Collected. Collected — the subset of Published whose definition loads and passes `Get-ScoutCollectorDefinition`'s schema validation without throwing. A manifest that fails validation is shipped but does not actually collect anything, so it must not count toward the coverage figure. .PARAMETER CollectorRoot The collector manifest tree. Defaults to `manifests/collectors` beside the module. .PARAMETER Category Restrict the result to these category (folder) names. Defaults to every category found. .OUTPUTS One [PSCustomObject] per category: Category, Published, Collected, Services (one entry per `.psd1` file: Name, Collected, Error). .NOTES Tracks ADO AB#7102 (feature AB#7101, AB#7103, AB#7104). #> function Get-ScoutCategoryCoverage { [CmdletBinding()] [OutputType([PSCustomObject])] param( [string]$CollectorRoot, [string[]]$Category ) # Same standalone-dot-source contract as Get-ScoutGraphPermissionImpact: callable either as # part of the loaded module or dot-sourced on its own (tests, scripts). if (-not (Get-Command Get-ScoutCollectorDefinition -ErrorAction SilentlyContinue)) { . (Join-Path $PSScriptRoot 'Get-ScoutCollectorDefinition.ps1') } if ([string]::IsNullOrWhiteSpace($CollectorRoot)) { # $PSScriptRoot is <module>/src/pipeline, so the manifest tree is two levels up. $ModuleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) $CollectorRoot = Join-Path $ModuleRoot 'manifests' 'collectors' } if (-not (Test-Path -LiteralPath $CollectorRoot)) { Write-Warning "Get-ScoutCategoryCoverage: collector root not found at '$CollectorRoot'." return @() } $Folders = @(Get-ChildItem -LiteralPath $CollectorRoot -Directory | Sort-Object Name) if ($Category -and $Category -notcontains 'All') { $Folders = @($Folders | Where-Object { $_.Name -in $Category }) } foreach ($Folder in $Folders) { $Files = @(Get-ChildItem -LiteralPath $Folder.FullName -Filter '*.psd1' -File | Sort-Object BaseName) $Services = foreach ($File in $Files) { $IsCollected = $true $ErrorText = $null try { $null = Get-ScoutCollectorDefinition -Path $File.FullName } catch { $IsCollected = $false $ErrorText = $_.Exception.Message } [PSCustomObject]@{ Name = $File.BaseName Collected = $IsCollected Error = $ErrorText } } [PSCustomObject]@{ Category = $Folder.Name Published = $Files.Count Collected = @($Services | Where-Object { $_.Collected }).Count Services = @($Services) } } } |