core/public/Get-JaxEnvironments.ps1
|
function Get-JaxEnvironments { [CmdletBinding()] param ( [string] $RepoRoot = (Get-JaxRepoRoot), [System.Collections.IDictionary] $Config ) if ($null -eq $Config) { $Config = Get-JaxConfig -RepoRoot $RepoRoot } $Config = Convert-JaxConfig -Config $Config $commonPSBoundParameters = Get-JaxCommonParameters -BoundParameters $PSBoundParameters Write-Debug "FUNC: $($MyInvocation.MyCommand.Name) Args: $($PSBoundParameters | ConvertTo-Json -Depth 1 -Compress -WarningAction SilentlyContinue)" $dummyEnvConfig = @{} if ($Config.Keys -contains 'dummyEnv') { if ($Config['dummyEnv'] -is [string]) { $dummyEnvConfig = @{ name = $Config['dummyEnv'] } } elseif ($Config['dummyEnv'] -is [System.Collections.IDictionary]) { $dummyEnvConfig = $Config['dummyEnv'] } } $dummyEnabled = $true if ($dummyEnvConfig.Keys -contains 'enabled') { $dummyEnabled = [bool]$dummyEnvConfig['enabled'] } $dummyName = 'none' if ($dummyEnvConfig.Keys -contains 'name' -and -not [string]::IsNullOrWhiteSpace([string]$dummyEnvConfig['name'])) { $dummyName = [string]$dummyEnvConfig['name'] } $dummySkipEnvRoot = $true if ($dummyEnvConfig.Keys -contains 'skipEnvRoot') { $dummySkipEnvRoot = [bool]$dummyEnvConfig['skipEnvRoot'] } function New-JaxDummyEnvironment { param ( [string] $Name, [bool] $SkipEnvRoot ) return [pscustomobject]@{ Name = $Name EnvDir = $null FlowDir = $null FlowConfigs = @() HierarchyPaths = @() HierarchyFlowDirs = @() IsDummy = $true SkipEnvRoot = $SkipEnvRoot } } $envs = @() $envRootPath = Join-Path $RepoRoot $Config.envRoot if (Test-Path -Path $envRootPath -PathType Container) { $envRootPath = (Resolve-Path $envRootPath).Path $flowDirNames = @($Config.flowDirNames) $flowDirs = Find-JaxFlowDirs -EnvRootPath $envRootPath -FlowDirNames $flowDirNames -CommonParameters $commonPSBoundParameters foreach ($flowDir in $flowDirs) { $envDir = Split-Path -Path $flowDir.FullName -Parent $envRelative = $envDir.Substring($envRootPath.Length).TrimStart([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar) $envName = $envRelative -replace '\\', '/' $hierarchyPaths = Get-JaxEnvHierarchyPaths -RepoRoot $RepoRoot -Config $Config -EnvDir $envDir $hierarchyFlowDirs = New-Object 'System.Collections.Generic.List[string]' $flowDirSeen = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) foreach ($path in $hierarchyPaths) { foreach ($flowDirName in $flowDirNames) { $candidate = Join-Path $path $flowDirName if (Test-Path -Path $candidate -PathType Container) { $resolved = (Resolve-Path $candidate).Path if ($flowDirSeen.Add($resolved)) { $hierarchyFlowDirs.Add($resolved) | Out-Null } } } } $flowConfigs = @() $flowConfigIndex = New-Object 'System.Collections.Generic.Dictionary[string, object]' ([System.StringComparer]::OrdinalIgnoreCase) $flowConfigOrder = New-Object 'System.Collections.Generic.List[string]' foreach ($flowDirPath in $hierarchyFlowDirs) { $flowFiles = @() foreach ($pattern in $Config.flowFilePatterns) { $flowFiles += Get-ChildItem -Path $flowDirPath -Filter $pattern -File -ErrorAction SilentlyContinue } $flowFiles = $flowFiles | Sort-Object -Property FullName -Unique foreach ($flowFile in $flowFiles) { $configKey = [IO.Path]::GetFileNameWithoutExtension($flowFile.Name) if (-not $flowConfigIndex.ContainsKey($configKey)) { $entry = New-JaxFlowConfig -EnvName $envName -ConfigFile $flowFile $entry | Add-Member -NotePropertyName ConfigPaths -NotePropertyValue @() -Force $flowConfigIndex[$configKey] = $entry $flowConfigOrder.Add($configKey) | Out-Null } $entry = $flowConfigIndex[$configKey] $resolvedPath = (Resolve-Path $flowFile.FullName).Path $entry.ConfigPaths += $resolvedPath $entry.ConfigPath = $resolvedPath $entry.FlowDirPath = (Resolve-Path $flowDirPath).Path $entry.EnvDirPath = (Resolve-Path (Split-Path -Parent $flowDirPath)).Path } } foreach ($key in $flowConfigOrder) { $flowConfigs += $flowConfigIndex[$key] } $envs += [pscustomobject]@{ Name = $envName EnvDir = $envDir FlowDir = $flowDir.FullName FlowConfigs = $flowConfigs HierarchyPaths = $hierarchyPaths HierarchyFlowDirs = @($hierarchyFlowDirs) } } } $conventionalEnvRoots = @() if ($Config.Keys -contains 'conventionalEnvRoots') { $conventionalEnvRoots = @($Config['conventionalEnvRoots']) } elseif ($Config.Keys -contains 'buildEnvRoots') { # Legacy alias — Convert-JaxConfig normally normalizes this, but read it # defensively here in case a caller passes a raw config. $conventionalEnvRoots = @($Config['buildEnvRoots']) } $conventionalEnvRoots = @($conventionalEnvRoots | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) if ($conventionalEnvRoots.Count -gt 0) { $psakePattern = 'psakefile*.ps1' $hasPsakePatternOverride = ($null -ne $Config.tasks) -and ($null -ne $Config.tasks.psakeFilePattern) if ($hasPsakePatternOverride) { $psakePattern = [string]$Config.tasks.psakeFilePattern } $existingNames = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) foreach ($envEntry in $envs) { $envEntryHasName = ($null -ne $envEntry) -and ($envEntry.PSObject.Properties.Match('Name').Count -gt 0) if ($envEntryHasName) { $existingNames.Add([string]$envEntry.Name) | Out-Null } } $seenDirs = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) $computedBuildCandidates = @() $relativeNameCounts = @{} foreach ($root in $conventionalEnvRoots) { $resolvedRoot = Resolve-JaxRepoRootedPath -Path $root -RepoRoot $RepoRoot @commonPSBoundParameters if (-not (Test-Path -Path $resolvedRoot -PathType Container)) { continue } $resolvedRoot = (Resolve-Path $resolvedRoot).Path $rootName = ([string]$root) -replace '\\', '/' $rootName = $rootName.Trim('/') if ([string]::IsNullOrWhiteSpace($rootName)) { continue } $psakeFiles = @(Get-ChildItem -Path $resolvedRoot -Filter $psakePattern -File -Recurse -ErrorAction SilentlyContinue) foreach ($psakeFile in $psakeFiles) { $moduleDir = Split-Path -Path $psakeFile.FullName -Parent if ([string]::IsNullOrWhiteSpace($moduleDir)) { continue } $resolvedModuleDir = (Resolve-Path $moduleDir).Path if (-not $seenDirs.Add($resolvedModuleDir)) { continue } $relative = $resolvedModuleDir.Substring($resolvedRoot.Length).TrimStart([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar) if ([string]::IsNullOrWhiteSpace($relative)) { continue } $relativeName = $relative -replace '\\', '/' $relativeNameKey = $relativeName.ToLowerInvariant() if (-not $relativeNameCounts.ContainsKey($relativeNameKey)) { $relativeNameCounts[$relativeNameKey] = 0 } $relativeNameCounts[$relativeNameKey]++ $computedBuildCandidates += [pscustomobject]@{ RootName = $rootName RelativeName = $relativeName RootedName = "$rootName/$relativeName" ModuleDir = $resolvedModuleDir } } } foreach ($buildCandidate in $computedBuildCandidates) { $relativeName = [string]$buildCandidate.RelativeName $relativeNameKey = $relativeName.ToLowerInvariant() $isRelativeNameUnique = ([int]$relativeNameCounts[$relativeNameKey]) -eq 1 $legacyName = "build/$relativeName" $rootedName = [string]$buildCandidate.RootedName $envName = if ($isRelativeNameUnique) { $legacyName } else { $rootedName } if (-not $existingNames.Add($envName)) { continue } $aliases = New-Object 'System.Collections.Generic.List[string]' if ($isRelativeNameUnique) { $aliases.Add($rootedName) | Out-Null $aliases.Add($relativeName) | Out-Null } $preferredCompletionName = if ($isRelativeNameUnique) { $relativeName } else { $rootedName } $hierarchyPaths = Get-JaxEnvHierarchyPaths -RepoRoot $RepoRoot -Config $Config -EnvDir $buildCandidate.ModuleDir @commonPSBoundParameters $envs += [pscustomobject]@{ Name = $envName Aliases = @($aliases) PreferredCompletionName = $preferredCompletionName EnvDir = $buildCandidate.ModuleDir FlowDir = $null FlowConfigs = @() HierarchyPaths = $hierarchyPaths HierarchyFlowDirs = @() IsComputed = $true } } } if ($dummyEnabled) { $hasDummy = $false foreach ($envEntry in $envs) { if ($envEntry -and $envEntry.PSObject.Properties.Match('Name').Count -gt 0) { if ([string]::Equals([string]$envEntry.Name, $dummyName, [System.StringComparison]::OrdinalIgnoreCase)) { $hasDummy = $true break } } } if (-not $hasDummy) { $envs += (New-JaxDummyEnvironment -Name $dummyName -SkipEnvRoot:$dummySkipEnvRoot) } } return $envs } |