functions/_Get-GistMapData.ps1
|
# <copyright file="_Get-GistMapData.ps1" company="Endjin Limited"> # Copyright (c) Endjin Limited. All rights reserved. # </copyright> <# .SYNOPSIS Internal helper function to read and parse the gist-map configuration. .DESCRIPTION This private function handles reading and parsing the gist-map configuration. It supports a remote-first loading strategy with local fallback: 1. HTTP fetch via Invoke-RestMethod (fast, works for public repos) 2. Git fetch via vendir (handles private repos with SSH/credential helpers) 3. Local file fallback from the module's gist-map.yml Results are cached for 30 seconds to improve tab-completion performance. .PARAMETER ScriptRoot The script root directory to use for locating the local gist-map.yml file. Used as a fallback when remote fetching fails. .PARAMETER GistMapUrl The URL to fetch the gist-map.yml file from via HTTP. When provided, the function attempts an HTTP fetch before falling back to other methods. .PARAMETER GistMapGitSource A hashtable containing 'url', 'ref', and 'path' keys for fetching the gist-map via vendir git sync. Used as a fallback when HTTP fetch fails. .PARAMETER NoCache When specified, bypasses the cache and forces a fresh read. .OUTPUTS Returns a hashtable containing the parsed gist-map data, or $null if all sources fail. .EXAMPLE _Get-GistMapData -ScriptRoot $PSScriptRoot .EXAMPLE _Get-GistMapData -ScriptRoot $PSScriptRoot -GistMapUrl 'https://raw.githubusercontent.com/endjin/endjin-gists/refs/heads/main/module/gist-map.yml' .EXAMPLE _Get-GistMapData -ScriptRoot $PSScriptRoot -NoCache .NOTES This is a private helper function (prefixed with '_') and is not exported from the module. Results are cached for 30 seconds to improve tab-completion performance. #> $script:cachedMap = $null $script:cacheTimestamp = [datetime]::MinValue $script:cacheTtlSeconds = 30 function _Get-GistMapData { [CmdletBinding()] param ( [Parameter()] [string] $ScriptRoot, [Parameter()] [string] $GistMapUrl, [Parameter()] [hashtable] $GistMapGitSource, [Parameter()] [switch] $NoCache ) # Return cached data if within TTL if (-not $NoCache -and $script:cachedMap -and ([datetime]::UtcNow - $script:cacheTimestamp).TotalSeconds -lt $script:cacheTtlSeconds) { return $script:cachedMap } $map = $null # 1. Try HTTP fetch if ($GistMapUrl) { try { Write-Verbose "Attempting HTTP fetch of gist-map from: $GistMapUrl" $yamlContent = Invoke-RestMethod -Uri $GistMapUrl -TimeoutSec 5 $map = $yamlContent | ConvertFrom-Yaml Write-Verbose "Successfully loaded gist-map via HTTP" } catch { Write-Verbose "HTTP fetch failed: $_" } } # 2. Try vendir git fetch if (-not $map -and $GistMapGitSource) { try { Write-Verbose "Attempting vendir git fetch of gist-map" $yamlContent = _Get-RemoteGistMap -GitSource $GistMapGitSource if ($yamlContent) { $map = $yamlContent | ConvertFrom-Yaml Write-Verbose "Successfully loaded gist-map via vendir" } } catch { Write-Verbose "Vendir git fetch failed: $_" } } # 3. Fallback to local file if (-not $map -and $ScriptRoot) { $mapPath = Join-Path $ScriptRoot 'gist-map.yml' if (Test-Path $mapPath) { Write-Verbose "Loading gist-map from local file: $mapPath" $map = Get-Content -Path $mapPath -Raw | ConvertFrom-Yaml Write-Verbose "Successfully loaded gist-map from local file" } } if (-not $map) { return $null } # Validate schema: every gist entry must have required fields $requiredFields = @('name', 'source', 'ref', 'includePaths') foreach ($groupName in $map.Keys) { foreach ($gist in $map[$groupName]) { foreach ($field in $requiredFields) { if (-not $gist.ContainsKey($field)) { throw "Gist '$($gist.name)' in group '$groupName' is missing required field: $field" } } } } $script:cachedMap = $map $script:cacheTimestamp = [datetime]::UtcNow return $map } |