functions/Compare-StagingConfig.ps1

[cmdletbinding]
function Get-ConfigFile(
    [string] $Path = "."
) {
    $configname = "web.config"
    
    if (!(test-path (join-path $path $configname))) {
        $files = gci $Path -Filter "*.exe.config" | ? { $_.Name -notlike "*.vshost.exe.config" }
        if ($files -ne $null) {
            $configname = $files[0].Name
            write-verbose "Chosen config $configname for path $((get-item $path).FullName)"
        }
    }    
    if (!(test-path (Join-Path $path $configname))) {
        write-verbose "config $configname not found for path $((get-item $path).FullName)"
        return $null
    }
    return (get-item (Join-Path $path $configname))
}

function Get-RemoteFile($path, $session) {
    $content = icm -Session $Session { 
        param($Path, $enc) 
        if ($enc -ne $null) { 
            write-host "using encoding: $enc"
            # [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding($enc)
        }
        write-host "getting '$($path)'"            
        Get-Content ($path) -Encoding UTF8 | out-string 
        write-host "getting '$($path)' DONE"
    } `
        -ArgumentList $Path, $([Console]::OutputEncoding.bodyname)
    return $content
}

function Compare-Files {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)][string] $source,
        [Parameter(Mandatory = $true)][string] $dest
    )
    $stagingPath = $source
    $currentPath = $dest
    # $srcFilename = Split-Path -Leaf $source
    # $dstFilename = Split-Path -Leaf $dest
    # $stagingPath = (join-path $env:TEMP "$srcFilename.staging.config")
    # $currentPath = (join-path $env:TEMP "$dstFilename.current.config")

    # if ($source -ne $stagingPath) { Copy-Item $source $stagingPath -Force }
    # if ($dest -ne $currentPath) { Copy-Item $source $currentPath -Force }
    $areequal = $false
    if ($null -ne (pathutils\where-is "diff.exe")) {
        write-host "running diff"
        $r = Process\invoke diff.exe @($stagingPath, $currentPath) -nothrow -Verbose
        if ($LASTEXITCODE -eq 0) { $areequal = $true }
    }
    else {
        Write-Warning "diff.exe not found on PATH."
    }

    if (!$areequal) {
        if ($promptpreference -ne "SilentlyContinue") {
            if ($null -ne (pathutils\where-is "kdiff3")) {
                write-host "running kdiff"
                $r = Process\invoke kdiff3 @($stagingPath, $currentPath) -nothrow -Verbose
            }
            else {
                Write-Warning "kdiff3 not found on PATH."
            }
        }
    }
}

function Compare-RemoteFiles {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)][string] $source,
        [Parameter(Mandatory = $true)][string] $dest,
        [Parameter(Mandatory = $true)][System.Management.Automation.Runspaces.PSSession] $Session = $null
    )

    if ($source.StartsWith("local:")) {
        $source = $source.Substring("local:".Length)
        write-host "using source file '$source'"
        $currentCfg = cat $source
    }
    else {
        Write-Host "downloading source file $source"
        $currentCfg = Get-RemoteFile -path $source -session $session
    }
    Write-Host "downloading dest file $dest"
    $stagingCfg = Get-RemoteFile -path $dest -session $session

    $srcFilename = Split-Path -Leaf $source        
    $stagingPath = (join-path $env:TEMP "$srcFilename.staging.config")
    $dstFilename = Split-Path -Leaf $dest
    $currentPath = (join-path $env:TEMP "$dstFilename.current.config")
    $currentCfg | Out-File $currentPath 
    $stagingCfg | Out-File $stagingPath 

    Compare-Files $currentPath $stagingPath
}
function Compare-StagingConfig { 
    [CmdletBinding()]
    param(
        [string] $Path = ".",
        [string] $stagingdir = $null,
        [System.Management.Automation.Runspaces.PSSession] $Session = $null
    ) 
    write-host "comparing staging config at '$path', session $session"
    $projectName = split-path -leaf $Path
    if ($projectName -match [regex]"(.*)-staging") {
        $projectName = $Matches[1]
    }

    if ([string]::IsNullOrEmpty($stagingDir)) {
        $stagingDir = "$Path\..\$projectName-staging"
    }

    if ($Session -ne $null) {

        if ($Path -eq ".") {
            $projectName = icm -Session $Session { param($Path) split-path -leaf $Path } -ArgumentList $Path
            $stagingDir = "$Path\..\$projectName-staging"
        }
        if ($path -eq $null) {
            throw "path cannot be null"
        }
        if ($stagingDir -eq $null) {
            throw "stagingdir cannot be null"
        }

        $configname = icm -Session $Session { 
            param($Path) 
            import-module require
            req beam.serverside -version 0.0.10
            (Get-ConfigFile $Path).Name 
        } -ArgumentList $Path
        if ($configname -eq $null) {
            throw "could not determine config file in path '$path'"
        }
        
        Compare-RemoteFiles (join-path $path $configname) (join-path $stagingDir $configname) -session $session
        
    }
    else {        
        $configname = Get-ConfigFile $Path
        if ($configname -ne $null) {
            if ($promptpreference -ne "SilentlyContinue") {
                $exitCode = start-executable kdiff3 @((join-path $path $configname.Name), (join-path $stagingDir $configname.Name))
            }
        }
        else {
            write-host "no config file found in $path"
        }
    }

    
    write-host "cmd exit code=$LASTEXITCODE. result=$exitCode"
}