core/public/Get-JaxShadowedTaskParameters.ps1
|
function Get-JaxShadowedTaskParameters { <# .SYNOPSIS Task/script parameters whose names Jax's own CLI flags already take. .DESCRIPTION Jax binds its own flags (-env, -client, -only, -noCache, ...) before it binds a task's parameters, and a task parameter sharing one of those names is dropped from the property bag instead of shadowing the flag. Left unreported the drop is silent, which is how `-client codex` came to select a Jax environment namespace while the psake task kept its default and registered the wrong client. Returns one entry per colliding name: Name - the parameter name Jax owns Entities - keys of the planned entities that declare it Supplied - $true when that flag was typed on this command line Callers decide what to do with each: a collision the user did not type is worth a warning, one they did type is an error, because the value they asked for cannot reach the task at all. #> [CmdletBinding()] param ( [object[]] $Entities, [Parameter(Mandatory = $true)] [string[]] $ReservedNames, [System.Collections.IDictionary] $SuppliedOptions, [hashtable] $Context = @{}, [hashtable] $CommonParameters = @{} ) if ($null -eq $Entities -or $Entities.Count -eq 0) { return @() } $reserved = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) foreach ($name in @($ReservedNames)) { if ([string]::IsNullOrWhiteSpace([string]$name)) { continue } $reserved.Add([string]$name) | Out-Null } # 'Command'/'CommandArgs' are Jax's positional parameters, not flags a user # would ever mean as a task parameter; reporting them would be noise. foreach ($name in @('Command', 'CommandArgs')) { $reserved.Remove($name) | Out-Null } $collisions = [ordered]@{} foreach ($entity in @($Entities)) { if ($entity -isnot [System.Collections.IDictionary]) { continue } $entityKey = [string]$entity['Key'] foreach ($declared in @(Get-JaxEntityDeclaredParameterNames -Entity $entity -Context $Context -CommonParameters $CommonParameters)) { if (-not $reserved.Contains($declared)) { continue } if (-not $collisions.Contains($declared)) { $collisions[$declared] = @() } if (-not [string]::IsNullOrWhiteSpace($entityKey) -and $collisions[$declared] -notcontains $entityKey) { $collisions[$declared] += $entityKey } } } $results = @() foreach ($name in @($collisions.Keys)) { $supplied = $false if ($null -ne $SuppliedOptions -and $SuppliedOptions.Contains($name)) { $value = $SuppliedOptions[$name] # A switch left at $false was not really asked for. $supplied = -not ($value -is [bool] -and -not $value) } $results += [ordered]@{ Name = $name Entities = @($collisions[$name]) Supplied = $supplied } } return $results } |