src/public/Execution/Get-AitherScriptMetadata.ps1
|
#Requires -Version 7.0 <# .SYNOPSIS Extract metadata from a script's comment block .DESCRIPTION Parses the header comment block of a script to extract metadata like Stage, Dependencies, Description, Category, Tags. .PARAMETER Path Path to the script file. This is a PATH, not a script number — to look a script up by number use `Get-AitherScript -Script <number> -Metadata`. A path that does not resolve is an error, not an empty result. .EXAMPLE Get-AitherScriptMetadata -Path "./library/automation-scripts/0402_Run-UnitTests.ps1" Extract metadata from a script file .EXAMPLE Get-AitherScript | ForEach-Object { Get-AitherScriptMetadata -Path $_.Path } Extract metadata from all scripts .OUTPUTS Hashtable - Metadata key-value pairs with Stage, Dependencies, Description, Category, Tags .NOTES Parses comment-based metadata from script headers. Returns default values if metadata not found. .LINK Get-AitherScript #> function Get-AitherScriptMetadata { [CmdletBinding()] param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [string]$Path ) process { try { $metadata = @{ Stage = 'Unknown' Dependencies = @() Description = '' Category = '' Tags = @() } # A path that does not resolve is a CALLER BUG, not "a script with no # metadata" — and returning the empty default for both made them # indistinguishable. `Get-AitherScriptMetadata 1002` silently produced # {Stage='Unknown'; Description=''; Tags=@()} and looked like a script # that simply had no header, when in fact nothing was ever read. # Fail loudly instead; the defaults below still apply when the file EXISTS # but carries no metadata block, which is the documented behaviour. if (-not (Test-Path $Path)) { if ($Path -match '^\d{4}$') { # The single most likely mistake: passing a script NUMBER to a # cmdlet that takes a PATH. Point at the cmdlet that does that. Write-Error -Message ( "Get-AitherScriptMetadata takes a script PATH, not a number. " + "For script $Path use: Get-AitherScript -Script $Path -Metadata" ) -Category InvalidArgument -TargetObject $Path return } Write-Error -Message "Script file not found: $Path" ` -Category ObjectNotFound -TargetObject $Path return } $content = Get-Content -Path $Path -Raw # Extract Stage (metadata is inside comment blocks without # prefix on each line) if ($content -match '(?m)^\s*Stage:\s*(.+)$') { $metadata.Stage = $matches[1].Trim() } # Extract Dependencies if ($content -match '(?m)^\s*Dependencies?:\s*(.+)$') { $deps = $matches[1].Trim() if ($deps -ne 'None' -and $deps -ne '') { $metadata.Dependencies = $deps -split '[,;]' | ForEach-Object { $_.Trim() } } } # Extract Description if ($content -match '(?m)^\s*Description:\s*(.+)$') { $metadata.Description = $matches[1].Trim() } # Extract Category if ($content -match '(?m)^\s*Category:\s*(.+)$') { $metadata.Category = $matches[1].Trim() } # Extract Tags if ($content -match '(?m)^\s*Tags?:\s*(.+)$') { $tags = $matches[1].Trim() $metadata.Tags = $tags -split '[,;]' | ForEach-Object { $_.Trim() } } return $metadata } catch { # Use fallback logging if Write-AitherLog not available during module load if (Get-Command Write-AitherLog -ErrorAction SilentlyContinue) { Write-AitherLog -Message "Error extracting script metadata: $($_.Exception.Message)" -Level Warning -Source 'Get-AitherScriptMetadata' -Exception $_ } return @{ Stage = 'Unknown' Dependencies = @() Description = '' Category = '' Tags = @() } } } } |