functions/_Get-RemoteGistMap.ps1

# <copyright file="_Get-RemoteGistMap.ps1" company="Endjin Limited">
# Copyright (c) Endjin Limited. All rights reserved.
# </copyright>

<#
.SYNOPSIS
    Internal helper to fetch a gist-map YAML file from a remote Git repository using vendir.
 
.DESCRIPTION
    This private function creates a temporary vendir configuration to sync a single file
    from a Git repository. It reuses the existing _Get-VendirPath resolution logic.
    Returns the raw YAML string on success, or $null on failure.
 
.PARAMETER GitSource
    A hashtable containing 'url', 'ref', and 'path' keys describing the Git repository,
    branch/tag, and file path within the repository.
 
.OUTPUTS
    Returns the raw YAML string content of the remote gist-map file, or $null if the
    fetch fails.
 
.EXAMPLE
    $yaml = _Get-RemoteGistMap -GitSource @{ url = 'https://github.com/endjin/endjin-gists.git'; ref = 'main'; path = 'module/gist-map.yml' }
 
.NOTES
    This is a private helper function (prefixed with '_') and is not exported from the module.
#>

function _Get-RemoteGistMap {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [hashtable] $GitSource
    )

    try {
        $vendirPath = _Get-VendirPath

        # Create a temporary directory for the vendir sync
        $tempDir = Join-Path ([System.IO.Path]::GetTempPath()) "endjin-gists-remote-$([System.Guid]::NewGuid().ToString('N').Substring(0, 8))"
        New-Item -ItemType Directory -Path $tempDir -Force | Out-Null

        Write-Verbose "Fetching remote gist-map via vendir to: $tempDir"

        # Determine the directory and filename from the path
        $filePath = $GitSource.path
        $fileName = Split-Path -Leaf $filePath
        $sourceDirectory = Split-Path -Parent $filePath

        # Build vendir config to sync the file
        $vendirConfig = [ordered]@{
            apiVersion  = 'vendir.k14s.io/v1alpha1'
            kind        = 'Config'
            directories = @(
                [ordered]@{
                    path     = 'sync'
                    contents = @(
                        @{
                            path         = '.'
                            git          = [ordered]@{
                                url = $GitSource.url
                                ref = $GitSource.ref
                            }
                            includePaths = @($fileName)
                        }
                    )
                }
            )
        }

        # Add newRootPath if the file is in a subdirectory
        if ($sourceDirectory) {
            # Normalise to forward slashes for vendir
            $sourceDirectory = $sourceDirectory -replace '\\', '/'
            $vendirConfig.directories[0].contents[0] += @{ newRootPath = $sourceDirectory }
        }

        $vendirFilePath = Join-Path $tempDir 'vendir.yml'
        ConvertTo-Yaml -Data $vendirConfig -OutFile $vendirFilePath -Force

        Write-Verbose "Generated vendir config for remote fetch:`n$(Get-Content -Raw $vendirFilePath)"

        # Run vendir sync in the temp directory
        Push-Location $tempDir
        try {
            $PSNativeCommandUseErrorActionPreference = $false
            $result = Invoke-Command { & $vendirPath sync --file 'vendir.yml' 2>&1 }
            $result | Write-Verbose

            if ($LASTEXITCODE -ne 0) {
                Write-Verbose "vendir sync failed with exit code $LASTEXITCODE"
                return $null
            }

            $syncedFile = Join-Path $tempDir 'sync' $fileName
            if (Test-Path $syncedFile) {
                $content = Get-Content -Path $syncedFile -Raw
                Write-Verbose "Successfully fetched remote gist-map ($($content.Length) bytes)"
                return $content
            }
            else {
                Write-Verbose "Synced file not found at: $syncedFile"
                return $null
            }
        }
        finally {
            Pop-Location
        }
    }
    catch {
        Write-Verbose "Failed to fetch remote gist-map via vendir: $_"
        return $null
    }
    finally {
        # Clean up temp directory
        if ($tempDir -and (Test-Path $tempDir)) {
            Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
        }
    }
}