Additions/Upgrade-AdditionInBranch.ps1

function Upgrade-AdditionInBranch
{
    Param(
        [Parameter(Mandatory=$false)]
        [ValidateSet('Replace','Compare')][string]$BespokeObjects = 'Replace',
        [Parameter(Mandatory=$false,Position=1)]
        [string]$AdditionPath,
        [Parameter(Mandatory=$false,Position=2)]
        [string]$TargetBranch,
        [Parameter(Mandatory=$false)]
        [string]$ResultPath,
        [Parameter(Mandatory=$false)]
        [int]$NewVersion,
        [Parameter(Mandatory=$false)]
        [int]$OldVersion,
        [Parameter(Mandatory=$false)]
        [string]$VersionPrefix,
        [Parameter(Mandatory=$false)]
        [switch]$Uninstall
    )

    $DeltaPath = ''

    if ($AdditionPath -eq '')
    {
        $AdditionPath = Get-TFSBranches -AdditionBranches | Out-GridView -Title 'Select the addition branch' -OutputMode Single
        if ($AdditionPath -eq '')
        {
            return
        }
    }

    if ($TargetBranch-eq '')
    {
        $TargetBranch = Get-TFSBranches | Out-GridView -Title 'Select the target branch' -OutputMode Single
        if ($TargetBranch -eq '')
        {
            return
        }
    }    
    
    if ($ResultPath -eq '')
    {
        $ResultPath = Join-Path ([Environment]::GetFolderPath('Desktop')) 'Result'
    }

    if ($OldVersion -eq '')
    {
        #what version of the addition is already in the addition?
        $CreateDeltaResult = Create-AdditionDeltaFromBase -AdditionPath $AdditionPath -NoContent

        $CurrentVersion = Get-AdditionVersionInBranch -BranchPath $TargetBranch -AdditionBranchPath $CreateDeltaResult.ReplacementsPath
        if ($CurrentVersion -ne '')
        {
            $OldVersion = Get-ChangesetNumberForVersionList -BranchPath $AdditionPath -VersionList $CurrentVersion
        }
    }

    if ($NewVersion -eq '')
    {
        $NewVersion = Get-ChangesetsInBranch -BranchPath $AdditionPath -ChangeSetOption Newest
    }
    
    if (($OldVersion -eq $NewVersion) -and (!$Uninstall))
    {
        Write-Host ('{0} is already at the latest version ({1}) of {2}' -f $TargetBranch, $NewVersion, $AdditionPath)
        return
    }

    if ($Uninstall)
    {
        $NewVersion = $OldVersion
        $OldVersion = ''
    }

    if ($OldVersion -eq '')
    {
        #create a delta between the addition and the base version
        if ($Uninstall)
        {
            $CreateDeltaResult = Create-AdditionDeltaFromBase -AdditionPath $AdditionPath -ChangesetNo $NewVersion -Reverse
        }
        else
        {
            $CreateDeltaResult = Create-AdditionDeltaFromBase -AdditionPath $AdditionPath -ChangesetNo $NewVersion
        }

    }
    else
    {
        #create a delta between the existing version and the latest version
        if ($Uninstall)
        {
            $CreateDeltaResult = Create-DeltaBetweenVersions -BranchPath $AdditionPath -BespokeObjects $BespokeObjects -OldVersion $OldVersion -NewVersion $NewVersion -DeltaPath (Create-TempDirectory) -Reverse
        }
        else
        {
            $CreateDeltaResult = Create-DeltaBetweenVersions -BranchPath $AdditionPath -BespokeObjects $BespokeObjects -OldVersion $OldVersion -NewVersion $NewVersion -DeltaPath (Create-TempDirectory)
        }
    }

    if ($VersionPrefix -eq '')
    {
        if (Test-Path $CreateDeltaResult.ReplacementsPath)
        {
            $VersionPrefix = Get-VersionPrefixFromDeltaPath $CreateDeltaResult.ReplacementsPath
        }
        else
        {
            $VersionPrefix = Get-VersionPrefixFromDeltaPath $CreateDeltaResult.DeltasPath
        }
        
        if ($VersionPrefix -eq '') 
        {
            if (($CreateDeltaResult.DeletedItemsPath) -and (Test-Path $CreateDeltaResult.DeletedItemsPath))
            {
                $VersionPrefix = Get-VersionPrefixFromDeltaPath $CreateDeltaResult.DeletedItemsPath
            }
        }
    }

    if ($Uninstall)
    {
        Apply-DeltaAndMergeVersionList -DeltaPath $CreateDeltaResult.DeltasPath -TargetPath $TargetBranch -ResultPath $ResultPath -DeltaVersionPrefix $VersionPrefix -Uninstall
    }
    else
    {
        Apply-DeltaAndMergeVersionList -DeltaPath $CreateDeltaResult.DeltasPath -TargetPath $TargetBranch -ResultPath $ResultPath -DeltaVersionPrefix $VersionPrefix
    }

   
    if (Test-Path $CreateDeltaResult.ReplacementsPath)
    {
        $ReplacementObjects = Get-ChildItem $CreateDeltaResult.ReplacementsPath
        foreach($ReplacementObject in $ReplacementObjects)
        {
            if ($ReplacementObject.Name -ne '_Replacement Objects.TXT')
            {
                [IO.File]::Copy($ReplacementObject.FullName,(Join-Path $ResultPath $ReplacementObject.Name))

                if ($Uninstall)
                {
                    Set-NAVApplicationObjectProperty -TargetPath (Join-Path $ResultPath $ReplacementObject.Name) -VersionListProperty 'DELETEME'
                }
            }
        }
        
        
        $OutputFile = (Join-Path $ResultPath 'Output\Output.TXT')

        if (Test-Path $OutputFile)
        {
            Remove-Item $OutputFile
        }

        Join-NAVApplicationObjectFile -Source $ResultPath -Destination $OutputFile
    }

    if (($CreateDeltaResult.DeletedItemsPath) -and (Test-Path $CreateDeltaResult.DeletedItemsPath))
    {
        $DeletedObjects = Get-ChildItem $CreateDeltaResult.DeletedItemsPath
        foreach($DeletedObject in $DeletedObjects)
        {
            [IO.File]::Copy($DeletedObject.FullName,(Join-Path $ResultPath $DeletedObject.Name))
            Set-NAVApplicationObjectProperty -TargetPath (Join-Path $ResultPath $DeletedObject.Name) -VersionListProperty 'DELETEME'
        }
        
        $OutputFile = (Join-Path $ResultPath 'Output\Output.TXT')

        if (Test-Path $OutputFile)
        {
            Remove-Item $OutputFile
        }

        Join-NAVApplicationObjectFile -Source $ResultPath -Destination $OutputFile
    }


    Remove-Item (Split-Path $CreateDeltaResult.DeltasPath -Parent) -Force -Recurse
    if ($DeltaPath -ne '')
    {
        Remove-Item $DeltaPath -Force -Recurse
    }
    
    Write-Host ''
    Write-Host ('{0} applied to {1}' -f $AdditionPath, $TargetBranch)    
    Write-Host ('Old version: {0} (Version List: {1})' -f $OldVersion, (Get-CommentForChangeset $OldVersion))
    Write-Host ('New version: {0} ({1})' -f $NewVersion, (Get-CommentForChangeset $NewVersion))
    Write-Host ('Version prefix: {0}' -f $VersionPrefix)

    if ($Uninstall)
    {
        Write-Host 'Complete the uninstallation by deleting objects with ''DELETEME'' in the Version List.'
    }
}

function Get-VersionPrefixFromDeltaPath
{
    Param(
        [Parameter(Mandatory=$true)]
        [string]$DeltaPath
    )

    $Prefixes = New-Object 'System.Collections.Generic.SortedList[System.Object,System.Object]'

    $Objects = Get-ChildItem $DeltaPath -File
    foreach ($Object in $Objects)
    {   
        [int]$Value = 0

        $CustomVersion = Get-CustomVersionList -VersionList (Get-NAVObjectVersion -ObjectFilePath $Object.FullName)
        if ($CustomVersion -ne '')
        {
            $Prefix = Get-AlphaPartOfVersionList -VersionList $CustomVersion
            if ($Prefixes.ContainsKey($Prefix))
            {
                if ($Prefixes.TryGetValue($Prefix,[ref]$Value))
                {
                    $Value += 1
                    $Prefixes.Item($Prefix) = $Value
                }
            }
            else
            {
                $Prefixes.Add($Prefix,1)
            }     
        }   
    }

    $CustomVersion = ''
    $Count = 0

    foreach ($Prefix in $Prefixes.Keys)
    {
        if ($Prefixes.TryGetValue($Prefix,[ref]$Value))
        {
            if ($Value -gt $Count)
            {
                $CustomVersion = $Prefix
                $Count = $Value
            }
        }
    }

    $CustomVersion
}

function Get-AlphaPartOfVersionList
{
    Param(
        [Parameter(Mandatory=$true)]
        [string]$VersionList
    )
    [int]$Result = 0

    for ($i = 0;$i -lt $VersionList.Length;$i++)
    {
        if ([Int]::TryParse($VersionList.Substring($i,1),[ref]$Result))
        {
            $VersionList.Substring(0,$i)
            return
        }
    }

    $VersionList
}

Export-ModuleMember -Function Upgrade-AdditionInBranch