Deltas/Apply-DeltaAndMergeVersionList.ps1

function Apply-DeltaAndMergeVersionList
(
    [Parameter(Mandatory=$true)]
    [string]$DeltaPath,
    [Parameter(Mandatory=$true)]
    [string]$TargetPath,
    [Parameter(Mandatory=$true)]
    [string]$ResultPath,
    [Parameter(Mandatory=$false)]
    [string]$DeltaVersionPrefix = '',
    [Parameter(Mandatory=$false)]
    [switch]$Uninstall
)
{
    [string]$TargetFilePath = ""
    [string]$DeltaContent = ""
    [string]$VersionList = ""    
    [string]$CustomVersionList = ""    
    [string]$TargetFileName = ""
    [string]$ResultFilePath = ""
    
    Create-EmptyDirectory $ResultPath

    #loop through the delta files in the folder, merge the version list with the target, apply the delta, then set the version list property
    if ($DeltaPath.StartsWith('$'))
    {
        Get-ObjectsFromTFSBranch -BranchPath $DeltaPath -DestinationPath (Join-Path $ResultPath 'Deltas') -Type Folder
        $DeltaPath = (Join-Path $ResultPath 'Deltas')
    }

    $DeltaFiles = Get-ChildItem -Path $DeltaPath

    #if the target path specified begins with a $, then fetch the target files from the TFS branch
    if ($TargetPath.StartsWith('$'))
    {
        $TargetBranch = $TargetPath
        $TargetPath = Join-Path $ResultPath -ChildPath 'Target'
        Create-EmptyDirectory $TargetPath

        foreach ($DeltaFile in $DeltaFiles)
        {
            $TargetFileName = $DeltaFile.BaseName + ".TXT"
            $TargetFilePath = Join-Path -Path $TargetPath -ChildPath $TargetFileName

            if ([IO.File]::Exists($TargetFilePath))
            {
                [IO.File]::Delete($TargetFilePath)
            }

            $TargetFileContent = Invoke-TFSAPI -Url ('_apis/tfvc/items/{0}/{1}.TXT' -f $TargetBranch, $DeltaFile.BaseName) -SuppressError

            if ($null -ne $TargetFileContent)
            {
                Add-Content -Path $TargetFilePath -Value $TargetFileContent            
            }
        }        
    }
    else
    {
        $SourcePath = $TargetPath        
        $TargetPath = Join-Path $ResultPath -ChildPath 'Target'
        Create-EmptyDirectory $TargetPath
        foreach ($DeltaFile in $DeltaFiles)
        {
            $SourceFileName = $DeltaFile.BaseName + ".TXT"
            if([IO.File]::Exists((Join-Path $SourcePath $SourceFileName)))
            {
                [IO.File]::Copy((Join-Path $SourcePath $SourceFileName),(Join-Path $TargetPath $SourceFileName))
            }
        }
    }

    foreach ($DeltaFile in $DeltaFiles)
    {
        $DeltaContent = Get-Content $DeltaFile.FullName -Raw            
        $VersionList = Get-VersionList -ObjectFilePath $DeltaFile.FullName
        $CustomVersionList = ''
        if ($VersionList -ne '') 
        {
            $CustomVersionList = Get-CustomVersionList -VersionList $VersionList
        }

        $TargetFileName = $DeltaFile.BaseName + ".TXT"
        $TargetFilePath = Join-Path -Path $TargetPath -ChildPath $TargetFileName

        $ResultFilePath = Join-Path -Path $ResultPath -ChildPath $TargetFileName

        if ([System.IO.File]::Exists($TargetFilePath))
        {
            $VersionList = Get-VersionList -ObjectFilePath $TargetFilePath
            $VersionList = Get-TargetVersionList -VersionList $VersionList -DeltaVersionPrefix $DeltaVersionPrefix

            if ($CustomVersionList -ne "")
            {
                if ($VersionList -ne "")
                {
                    $VersionList += "," + $CustomVersionList
                }
                else
                {
                    $VersionList = $CustomVersionList
                }
            }        

            Update-NAVApplicationObject -DeltaPath $DeltaFile.FullName -TargetPath $TargetFilePath -ResultPath $ResultFilePath -DateTimeProperty Now -ModifiedProperty FromTarget -VersionListProperty Clear
            Set-NAVApplicationObjectProperty -TargetPath $ResultFilePath -VersionListProperty $VersionList
        }
        #if the object doesn't exist in the target just copy it across
        elseif (!$Uninstall)
        {
            [System.IO.File]::Copy($DeltaFile.FullName, $ResultFilePath)
        }
    }    

    [string]$ConflictPath = Join-Path $ResultPath -ChildPath "Conflict"
    [string]$OutputPath = Join-Path $ResultPath -ChildPath "Output"    
    [string]$OutputFile = Join-Path $OutputPath -ChildPath "Output.TXT"    
    [bool]$UnprocessedConflictsExist = $false

    Create-EmptyDirectory $ConflictPath
    Create-EmptyDirectory $OutputPath

    $ResultFiles = Get-ChildItem -Path $ResultPath
    foreach ($ResultFile in $ResultFiles)
    {
        if ($ResultFile.Extension -eq ".CONFLICT")
        {
            [string]$ConflictContent = Get-Content -Path $ResultFile.FullName
            if ($ConflictContent.IndexOf("ConflictHint=Unprocessed") -gt 0)
            {
                $UnprocessedConflictsExist = $true
            }

            $ConflictFile = Join-Path $ConflictPath -ChildPath $ResultFile.Name
            [System.IO.File]::Move($ResultFile.FullName, $ConflictFile)
        }
    }

    Join-NAVApplicationObjectFile -Source $ResultPath -Destination $OutputFile

    if ($UnprocessedConflictsExist)
    {
        [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
        [System.Windows.Forms.MessageBox]::Show("Some changes in the delta files have not been applied, please check the Conflicts folder.", "Unprocessed Conflicts")
    }
}

function Get-VersionList
(
    [Parameter(Mandatory=$true)]
    [string]$ObjectFilePath
)
{
    [string]$ObjectContent = Get-Content -Path $ObjectFilePath -Raw
    [int]$VersionListIndex = $ObjectContent.IndexOf("Version List=")
    [string]$VersionList = $ObjectContent.Substring($VersionListIndex + 13,$ObjectContent.IndexOf(";",$VersionListIndex) - ($VersionListIndex + 13))
    $VersionList
}

function Get-TargetVersionList
(
    [Parameter(Mandatory=$true)]
    [string]$VersionList,
    [Parameter(Mandatory=$false)]
    [string]$DeltaVersionPrefix = ''
)
{
    #get the version list of the target, minus the version of the delta that is being applied (if applicable)
    if ($DeltaVersionPrefix -eq '')
    {
        $VersionList
    }
    else
    {
        Get-VersionListExcludingPrefixes -VersionList $VersionList -VersionPrefixes $DeltaVersionPrefix
    }
}

function Get-CustomVersionList
(
    [Parameter(Mandatory=$true)]
    [string]$VersionList
)
{
    $VersionPrefixes = 'NAVW1', 'NAVGB'
    Get-VersionListExcludingPrefixes -VersionList $VersionList -VersionPrefixes $VersionPrefixes
}

function Get-VersionListExcludingPrefixes
(
    [Parameter(Mandatory=$true)]
    [string]$VersionList,
    [Parameter(Mandatory=$true)]
    $VersionPrefixes
)
{
    $Versions = @() + $VersionList.Split(',')
    foreach ($Prefix in $VersionPrefixes)
    {
        $Versions = $Versions.Where({!$_.StartsWith($Prefix)})
    }

    $Versions -join ','
}

Export-ModuleMember -Function Apply-DeltaAndMergeVersionList
Export-ModuleMember -Function Get-VersionList
Export-ModuleMember -Function Get-TargetVersionList
Export-ModuleMember -Function Get-CustomVersionList
Export-ModuleMember -Function Get-VersionListExcludingPrefixes