plugins/bob/private/Resolve-JaxBobScenarioItemRecursive.ps1
|
function Resolve-JaxBobScenarioItemRecursive { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $Key, [AllowNull()] $Value, [string] $ScenarioName, [string] $ProvenancePath, [hashtable] $Context, [int] $Depth = 20, [string[]] $Stack = @(), [switch] $StepMode, [switch] $IsLibraryItem ) if ($Depth -le 0) { throw "Max recursion depth reached while expanding scenario item '$Key'." } $library = $null if ($null -ne $Context -and $Context.ContainsKey('ScenarioLibrary')) { $library = $Context['ScenarioLibrary'] } if ($null -eq $Value) { if ($null -eq $library -or $library -isnot [System.Collections.IDictionary]) { throw "Scenario item '$Key' references a library item, but no library is available." } if (-not $library.Contains($Key)) { throw "Library item '$Key' not found in scenarios-lib or suite.library." } if ($Stack -contains $Key) { throw "Recursive library reference detected: $($Stack -join ' -> ') -> $Key" } $nextStack = @($Stack + $Key) return Resolve-JaxBobScenarioItemRecursive -Key $Key -Value $library[$Key] -ScenarioName $ScenarioName -ProvenancePath $ProvenancePath -Context $Context -Depth ($Depth - 1) -Stack $nextStack -StepMode:$StepMode -IsLibraryItem } if ($Value -is [System.Collections.IDictionary] -and $Value.Contains('steps')) { return Resolve-JaxBobScenarioSteps -Steps $Value['steps'] -ScenarioName $ScenarioName -ProvenancePath $ProvenancePath -Context $Context -Depth ($Depth - 1) -Stack $Stack } if (($IsLibraryItem -or $StepMode) -and $Value -is [System.Collections.IEnumerable] -and $Value -isnot [string] -and $Value -isnot [System.Collections.IDictionary]) { return Resolve-JaxBobScenarioSteps -Steps $Value -ScenarioName $ScenarioName -ProvenancePath $ProvenancePath -Context $Context -Depth ($Depth - 1) -Stack $Stack } if ($StepMode -and $Value -is [string] -and $library -and $library -is [System.Collections.IDictionary] -and $library.Contains($Value)) { if ($Stack -contains $Value) { throw "Recursive library reference detected: $($Stack -join ' -> ') -> $Value" } $nextStack = @($Stack + $Value) return Resolve-JaxBobScenarioItemRecursive -Key $Value -Value $library[$Value] -ScenarioName $ScenarioName -ProvenancePath $ProvenancePath -Context $Context -Depth ($Depth - 1) -Stack $nextStack -StepMode -IsLibraryItem } # In StepMode, a string step value can be a reference to another scenario item in the same scenario config. # Prefer resolving it before treating it as a raw psake task name. if ($StepMode -and $Value -is [string] -and $null -ne $Context -and $Context.ContainsKey('ScenarioItemDefinitions') -and $Context['ScenarioItemDefinitions'] -is [System.Collections.IDictionary]) { $defs = $Context['ScenarioItemDefinitions'] if ($defs.Contains($Value) -and $null -ne $defs[$Value]) { $scenarioRef = "scenario:$Value" if ($Stack -contains $scenarioRef) { throw "Recursive scenario reference detected: $($Stack -join ' -> ') -> $scenarioRef" } $nextStack = @($Stack + $scenarioRef) return Resolve-JaxBobScenarioItemRecursive -Key $Value -Value $defs[$Value] -ScenarioName $ScenarioName -ProvenancePath $ProvenancePath -Context $Context -Depth ($Depth - 1) -Stack $nextStack -StepMode -IsLibraryItem:$IsLibraryItem } } # In StepMode, a string step value can be a reference to a scenario-defined entity (not a psake task name). # Prefer resolving it via ScenarioEntityIndex when available so args (e.g. stepName) and runner/script/task # definitions are preserved. Fallback to normal string handling when not found. if ($StepMode -and $Value -is [string] -and $null -ne $Context -and $Context.ContainsKey('ScenarioEntityIndex') -and $Context['ScenarioEntityIndex'] -is [System.Collections.IDictionary]) { $idx = $Context['ScenarioEntityIndex'] $normalized = Convert-JaxRunEntityName -Name $Value $resolved = $null if (-not [string]::IsNullOrWhiteSpace($normalized) -and $idx.ContainsKey($normalized)) { $resolved = $idx[$normalized] } elseif ($idx.ContainsKey($Value)) { $resolved = $idx[$Value] } if ($resolved -is [System.Collections.IDictionary]) { return @($resolved) } } $entity = Resolve-JaxScenarioItemToRunEntity -Key $Key -Value $Value -ScenarioName $ScenarioName -ProvenancePath $ProvenancePath -Context $Context if ($null -eq $entity) { return @() } return @($entity) } |