functions/Get-ExtensionFromGitRepository.ps1

# <copyright file="Get-ExtensionFromGitRepository.ps1" company="Endjin Limited">
# Copyright (c) Endjin Limited. All rights reserved.
# </copyright>
function Get-ExtensionFromGitRepository {
    [CmdletBinding()]
    [OutputType([hashtable])]
    param(
        [Parameter(Mandatory)]
        [string] $Name,

        [Parameter(Mandatory)]
        [uri] $RepositoryUri,

        [Parameter()]
        [string] $RepositoryFolderPath = 'module',

        [Parameter(Mandatory)]
        [string] $TargetPath,

        [Parameter(Mandatory)]
        [string] $GitRef,

        [Parameter()]
        [bool] $UseEphemeralVendirConfig = $true
    )

    # This function uses the 'vendir' tool to download the extension from the Git repository.

    $safeGitRef = $GitRef.Replace('/', '-')
    $existingExtensionPath,$existingExtensionVersion = Get-InstalledExtensionDetails -Name $Name -TargetPath $TargetPath -GitRefAsFolderName $safeGitRef
    $zfRoot = Split-Path $TargetPath -Parent

    # Handle getting the module from the repository
    if (!$existingExtensionPath -or $existingExtensionVersion -ne $safeGitRef) {
        if (!$existingExtensionPath) {
            Write-Verbose "Extension '$Name' not found locally."
        }
        elseif ($existingExtensionVersion -ne $safeGitRef) {
            Write-Verbose "Extension '$Name' found locally but version mismatch detected. Found: '$existingExtensionVersion'; Required: '$safeGitRef' [$GitRef]"
        }
        Write-Host "Installing extension $Name from $RepositoryUri" -f Cyan
        
        # Check whether the vendir tool is available by PATH and install it if not
        $vendirTool = 'vendir'
        if (!(Get-Command $vendirTool -ErrorAction SilentlyContinue)) {
            $installDir = Join-Path $zfRoot 'bin'
            $vendirTool = _installVendir -ToolName 'vendir' -InstallDir $installDir
        }

        $cacheDir = Join-Path $zfRoot '.cache'
        # Currently we treat the generated vendir config files as ephemeral and extension-specific
        $vendirConfigPath = Join-Path $cacheDir "zf.$Name.vendir.yml"

        Update-VendirConfig `
            -Name $Name `
            -RepositoryUri $RepositoryUri `
            -GitRef $GitRef `
            -RepositoryFolderPath $RepositoryFolderPath `
            -ConfigPath $vendirConfigPath `
            -TargetPath (Join-Path $TargetPath $Name $safeGitRef)
        
        Write-Verbose "Running vendir sync with config: $vendirConfigPath"
        Get-Content $vendirConfigPath | Write-Verbose
        try {
            # Run vendir and capture/handle any errors
            $PSNativeCommandUseErrorActionPreference = $true
            Invoke-Command { & $vendirTool sync -f $vendirConfigPath --chdir $cacheDir } -ErrorVariable vendirErrors -ErrorAction Stop | Write-Verbose
        }
        catch {
            throw "Error whilst trying to run vendir: $($_.Exception.Message) [ExitCode=$LASTEXITCODE]`n$vendirErrors"
        }



        $existingExtensionPath,$existingExtensionVersion = Get-InstalledExtensionDetails -Name $Name -TargetPath $TargetPath -GitRefAsFolderName $safeGitRef
        if (!$existingExtensionPath) {
            throw "Failed to install extension $Name ($GitRef) from $RepositoryUri repository"
        }
        Write-Host "INSTALLED MODULE: $Name ($existingExtensionVersion)" -f Cyan

        if ($UseEphemeralVendirConfig) {
            Remove-Item $vendirConfigPath -Force
        }
    }
    else {
        Write-Host "FOUND MODULE: $Name ($existingExtensionVersion)" -f Cyan
    }

    # Return the additional extension metadata that this function has populated
    $additionalMetadata = @{
        Path = $existingExtensionPath
        Enabled = $true
        Version = $GitRef
    }

    return $additionalMetadata
}