Pipelines/Apply-DirectoryAppProps.ps1

Param(
    [Parameter(Mandatory=$true)]
    [string] $baseFolder
)

function Replace-VariablesInText {
    Param(
        [string] $content,
        [hashtable] $variables
    )
    
    # Replace variables: $(variableName)
    $variables.Keys | ForEach-Object {
        $variableName = $_
        $variableValue = $variables[$_]
        # Use string concatenation to avoid PowerShell interpolation
        $pattern = '$(' + $variableName + ')'
        $content = $content.Replace($pattern, $variableValue)
    }
    
    return $content
}

function Merge-JsonProperties {
    Param(
        [string] $targetJsonPath,
        [PSCustomObject] $sourcePropertiesObj,
        [hashtable] $variables
    )
    
    # Read target JSON
    $targetContent = Get-Content $targetJsonPath -Raw -Encoding UTF8
    $originalContent = $targetContent
    
    # Step 1: Replace variables
    if ($variables.Count -gt 0) {
        $targetContent = Replace-VariablesInText -content $targetContent -variables $variables
    }
    
    # Step 2: Parse target JSON
    $targetObj = $targetContent | ConvertFrom-Json
    
    # Step 3: Add missing properties from source
    $modified = $false
    
    $sourcePropertiesObj.PSObject.Properties | ForEach-Object {
        $propName = $_.Name
        
        if ($targetObj.PSObject.Properties.Name -notcontains $propName) {
            Write-Host " Adding property '$propName'"
            $targetObj | Add-Member -MemberType NoteProperty -Name $propName -Value $_.Value -Force
            $modified = $true
        }
        else {
            Write-Host " Skipping property '$propName' (already defined in app.json)"
        }
    }
    
    # Step 4: Save if modified
    if ($modified -or ($targetContent -ne $originalContent)) {
        $json = $targetObj | ConvertTo-Json -Depth 100
        $json = $json -replace '\r?\n', "`r`n"
        $json | Set-Content -Path $targetJsonPath -Encoding UTF8 -NoNewline
        
        # Verify JSON is valid
        $null = Get-Content $targetJsonPath -Raw | ConvertFrom-Json
        Write-Host " ✓ Saved"
    }
}

# Find directory.app.props.json
$directoryPropsPath = Join-Path $baseFolder "directory.app.props.json"

if (-not (Test-Path $directoryPropsPath)) {
    Write-Host "directory.app.props.json not found at $directoryPropsPath, skipping processing"
    return
}

Write-Host "##[group]Applying directory.app.props.json configuration"

# Parse directory.app.props.json
$directoryPropsContent = Get-Content $directoryPropsPath -Raw
$directoryProps = $directoryPropsContent | ConvertFrom-Json

# Extract variables
$variables = @{}
if ($directoryProps.PSObject.Properties.Name -contains 'variables') {
    Write-Host "Variables:"
    $directoryProps.variables.PSObject.Properties | ForEach-Object {
        $variables[$_.Name] = $_.Value
        Write-Host " $($_.Name) = $($_.Value)"
    }
}

# Get properties object
$sourcePropertiesObj = $null
if ($directoryProps.PSObject.Properties.Name -contains 'properties') {
    Write-Host "Properties to add/update in app.json:"
    $sourcePropertiesObj = $directoryProps.properties
    
    # Display properties for logging
    $directoryProps.properties.PSObject.Properties | ForEach-Object {
        Write-Host " $($_.Name) = $($_.Value)"
    }
}

# Find all app.json files
$appJsonFiles = Get-ChildItem -Path $baseFolder -Filter "app.json" -Recurse -File | Where-Object {
    $_.FullName -notlike "*\.git\*" -and 
    $_.FullName -notlike "*\.alpackages\*" -and
    $_.FullName -notlike "*\.output\*" -and
    $_.FullName -notlike "*\.packages\*"
}

Write-Host "Found $($appJsonFiles.Count) app.json file(s)"

# Process each app.json
foreach ($appJsonFile in $appJsonFiles) {
    Write-Host "##[group]Processing: $($appJsonFile.FullName.Replace($baseFolder, '').TrimStart('\', '/'))"
    try {
        Merge-JsonProperties -targetJsonPath $appJsonFile.FullName -sourcePropertiesObj $sourcePropertiesObj -variables $variables
    }
    catch {
        Write-Error " ✗ Error processing: $_"
        throw
    }
    finally {
        Write-Host "##[endgroup]"
    }
}

Write-Host "✓ directory.app.props.json processing completed"
Write-Host "##[endgroup]"