Deltas/Create-DeltaBetweenVersions.ps1
function Create-DeltaBetweenVersions { Param( [Parameter(Mandatory=$true)] [string]$BranchPath, [Parameter(Mandatory=$true)] [int]$OldVersion, [Parameter(Mandatory=$true)] [int]$NewVersion, [Parameter(Mandatory=$true)] [ValidateSet('Replace','Compare')][string]$BespokeObjects = 'Replace', [Parameter(Mandatory=$false)] [string]$DeltaPath, [Parameter(Mandatory=$false)] [switch]$NoContent, [Parameter(Mandatory=$false)] [switch]$Reverse ) #download the list of items at both versions $url = '_apis/tfvc/items?scopePath={0}&recursionLevel=OneLevel&versionType=Changeset&version={1}' -f $BranchPath, $OldVersion $OldItems = Invoke-TFSAPI -Url $url $url = '_apis/tfvc/items?scopePath={0}&recursionLevel=OneLevel&versionType=Changeset&version={1}' -f $BranchPath, $NewVersion $NewItems = Invoke-TFSAPI -Url $url if ($DeltaPath -eq '') { $DeltaPath = Join-Path ([Environment]::GetFolderPath('Desktop')) ('{0} - {1}' -f $OldVersion, $NewVersion) } $OldItemsFolder = Join-Path $DeltaPath $OldVersion $NewItemsFolder = Join-Path $DeltaPath $NewVersion $DeltasFolder = Join-Path $DeltaPath 'Deltas' $ReplacementFolder = Join-Path $DeltaPath 'Replacement Objects' $DeletedItemsFolder = Join-Path $DeltaPath 'Deleted Items' $ResultObject = New-Object System.Object $ResultObject | Add-Member -Type NoteProperty -Name 'DeltasPath' -Value $DeltasFolder $ResultObject | Add-Member -Type NoteProperty -Name 'ReplacementsPath' -Value $ReplacementFolder $ResultObject | Add-Member -Type NoteProperty -Name 'DeletedItemsPath' -Value $DeletedItemsFolder Create-EmptyDirectory $OldItemsFolder Create-EmptyDirectory $NewItemsFolder Create-EmptyDirectory $DeltasFolder $progressName = "Comparing changesets {0} and {1}" -f $OldVersion, $NewVersion Write-Progress $progressName [int]$itemCounter = 0 $DeletedItems = Compare-Object -ReferenceObject $olditems.value -DifferenceObject $newitems.value -Property path | Where-Object -property SideIndicator -EQ "<=" $OldItems = $OldItems.Value | Sort-Object -Property Version -Descending $NewItems = $NewItems.Value | Where-Object -Property Version -gt $OldItems[0].Version $itemCounter = 0 foreach ($NewItem in $NewItems) { $itemCounter += 1 if ($NewItems.Count) { Write-Progress $progressName -PercentComplete (($itemCounter / $NewItems.Count) * 100) } if (!$NewItem.isFolder) { if ($NoContent) { if (![IO.Directory]::Exists($ReplacementFolder)) { [IO.Directory]::CreateDirectory($ReplacementFolder) } New-Item -ItemType File -Path (Join-Path -Path $ReplacementFolder -ChildPath (Split-Path -Leaf $NewItem.Path)) | Out-Null } else { Add-Content -Path (Join-Path -Path $NewItemsFolder -ChildPath (Split-Path -Leaf $NewItem.Path)) -Value (Invoke-TFSAPI -Url $NewItem.url) if ((IsStandardObject -ObjectName (Split-Path -Leaf $NewItem.Path)) -or ($BespokeObjects -eq 'Compare')) { $OldItem = $OldItems | Where-Object -Property Path -EQ -Value $NewItem.Path if ($OldItem.Path -ne $null) { Add-Content -Path (Join-Path -Path $OldItemsFolder -ChildPath (Split-Path -Leaf $OldItem.Path)) -Value (Invoke-TFSAPI -Url $OldItem.url) } } else { if (![IO.Directory]::Exists($ReplacementFolder)) { [IO.Directory]::CreateDirectory($ReplacementFolder) } [IO.File]::Move((Join-Path -Path $NewItemsFolder -ChildPath (Split-Path -Leaf $NewItem.Path)),(Join-Path -Path $ReplacementFolder (Split-Path -Leaf $NewItem.Path))) } } } } foreach ($DeletedItem in $DeletedItems) { if (!$NoContent) { if (![IO.Directory]::Exists($DeletedItemsFolder)) { [IO.Directory]::CreateDirectory($DeletedItemsFolder) } $OldItem = $OldItems | Where-Object -Property Path -EQ -Value $DeletedItem.Path if ($OldItem.Path -ne $null) { Add-Content -Path (Join-Path -Path $DeletedItemsFolder -ChildPath (Split-Path -Leaf $OldItem.Path)) -Value (Invoke-TFSAPI -Url $OldItem.url) } } } if ($Reverse) { Compare-NAVApplicationObject -OriginalPath $NewItemsFolder -ModifiedPath $OldItemsFolder -DeltaPath $DeltasFolder -Force } else { Compare-NAVApplicationObject -OriginalPath $OldItemsFolder -ModifiedPath $NewItemsFolder -DeltaPath $DeltasFolder -Force } if ([IO.Directory]::Exists($ReplacementFolder)) { Join-NAVApplicationObjectFile -Source $ReplacementFolder -Destination (Join-Path $ReplacementFolder -ChildPath '_Replacement Objects.TXT') } $ResultObject } function IsStandardObject ( [Parameter(Mandatory=$true)] [string]$ObjectName ) { [bool]$Result = $false #read the numerical part of the file name [int]$ObjectNumber = [int32]::Parse($ObjectName.Substring(3,$ObjectName.Length - 7)) if (($ObjectNumber -lt 50000) -or ($ObjectNumber -gt 90000000)) { $Result = $true } #special rules for menusuites if ($ObjectName.Substring(0,3) -eq "MEN") { if ($ObjectNumber -le 1050) { $Result = $true } else { $Result = $false } } $Result } Export-ModuleMember -Function Create-DeltaBetweenVersions |