215 lines
5.9 KiB
PowerShell
215 lines
5.9 KiB
PowerShell
|
function Copy-AlkamiReleaseManifest {
|
|||
|
<#
|
|||
|
.SYNOPSIS
|
|||
|
Copies Orb with a file manifest to track files between releases.
|
|||
|
Files that are not tracked by the manifest are left alone.
|
|||
|
DiffMove flag makes it so that unchanged files are not copied.
|
|||
|
#>
|
|||
|
[CmdletBinding()]
|
|||
|
Param (
|
|||
|
[Parameter(Mandatory=$false)]
|
|||
|
[Alias("TempOrbPath")]
|
|||
|
[string]$srcPath = "C:\temp\deploy\orb",
|
|||
|
|
|||
|
[Parameter(Mandatory=$false)]
|
|||
|
[Alias("OrbPath")]
|
|||
|
[string]$dstPath,
|
|||
|
|
|||
|
[Parameter(Mandatory=$false)]
|
|||
|
[switch] $diffMove
|
|||
|
)
|
|||
|
|
|||
|
$logLead = (Get-LogLeadName);
|
|||
|
|
|||
|
if([string]::IsNullOrEmpty($dstPath)) {
|
|||
|
$dstPath = (Get-OrbPath)
|
|||
|
}
|
|||
|
|
|||
|
if($dstPath -eq $srcPath)
|
|||
|
{
|
|||
|
Write-Warning "$logLead Cannot copy Alkami release from/to the same folder. $srcPath"
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
$timer = [System.Diagnostics.Stopwatch]::StartNew()
|
|||
|
|
|||
|
$manifestPath = Join-Path $dstPath "manifest.txt"
|
|||
|
$manifestLeftoverPath = Join-Path $dstPath "manifestLeftovers.txt"
|
|||
|
|
|||
|
$exclude = "*log4net.config"
|
|||
|
|
|||
|
Write-Host "$logLead Discovering files to copy:"
|
|||
|
Write-Host "$logLead Note: log4net.config files are ignored!"
|
|||
|
Write-Host "$loglead Discovering files in $srcPath"
|
|||
|
$srcFiles = (Get-RelativeFileList $srcPath -exclude $exclude)
|
|||
|
|
|||
|
$dstFiles = @();
|
|||
|
if(Test-Path $manifestPath)
|
|||
|
{
|
|||
|
Write-Host "$loglead Loading file paths from manifest file: $manifestPath"
|
|||
|
$dstFiles = (Get-Content $manifestPath)
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Write-Host "$logLead Release manifest not detected at $manifestPath"
|
|||
|
Write-Host "$logLead Discovering files in $dstPath"
|
|||
|
$dstFiles = (Get-RelativeFileList $dstPath -exclude $exclude)
|
|||
|
}
|
|||
|
|
|||
|
Write-Host "`n$logLead Copying Alkami release from $srcPath to $dstPath"
|
|||
|
Write-Host "$logLead Determining files to add."
|
|||
|
$filesToAdd = (Get-SetDifference $srcFiles $dstFiles)
|
|||
|
Write-Host "$logLead Determining files to delete."
|
|||
|
$filesToDelete = (Get-SetDifference $dstFiles $srcFiles)
|
|||
|
Write-Host "$logLead Determining files to move."
|
|||
|
$filesToMove = @();
|
|||
|
$filesToMove = (Get-SetDifference $srcFiles $filesToAdd);
|
|||
|
$filesToMove = (Get-SetDifference $filesToMove $filesToDelete)
|
|||
|
|
|||
|
if($diffMove.isPresent)
|
|||
|
{
|
|||
|
Write-Host "$logLead DiffMove flag is present. Finding files that have not changed to avoid copies."
|
|||
|
|
|||
|
# Only move the files that have changed by hash comparison.
|
|||
|
$newFilesToMove = @();
|
|||
|
foreach($file in $filesToMove)
|
|||
|
{
|
|||
|
$srcFile = Join-Path $srcPath $file
|
|||
|
$dstFile = Join-Path $dstPath $file
|
|||
|
if((Get-FileHash -path $srcFile).hash -ne (Get-FileHash -path $dstFile).hash)
|
|||
|
{
|
|||
|
Write-Verbose "$logLead $srcFile hash is different than $dstFile hash."
|
|||
|
$newFilesToMove += $file
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
# Reassign $filesToMove to a list of fewer files to copy.
|
|||
|
$count = $filesToMove.Count
|
|||
|
$filesToMove = $newFilesToMove
|
|||
|
$count = $count - $filesToMove.Count
|
|||
|
Write-Host "$logLead $count files don't need to be updated!"
|
|||
|
}
|
|||
|
|
|||
|
$addCount = $filesToAdd.count;
|
|||
|
$delCount = $filesToDelete.count;
|
|||
|
$movCount = $filesToMove.count;
|
|||
|
|
|||
|
Write-Host "`n$logLead Peforming the following actions:"
|
|||
|
Write-Host "$logLead Adding $addCount new files."
|
|||
|
Write-Host "$logLead Copying $movCount files."
|
|||
|
Write-Host "$logLead Deleting $delCount existing files.`n"
|
|||
|
|
|||
|
$filesToCopy = $filesToAdd + $filesToMove
|
|||
|
if($filesToCopy.Count)
|
|||
|
{
|
|||
|
Write-Host "$logLead Starting file copies."
|
|||
|
|
|||
|
$filesPerJob = 3000;
|
|||
|
$maxJobs = 8;
|
|||
|
$numFiles = $filesToCopy.Count
|
|||
|
$numJobs = [Math]::Ceiling($numFiles / $filesPerJob);
|
|||
|
Write-Host "NumJobs $numJobs"
|
|||
|
|
|||
|
$scriptBlock = {
|
|||
|
|
|||
|
param ($srcPath, $dstPath, $copyFiles)
|
|||
|
|
|||
|
$VerbosePreference = 'Continue'
|
|||
|
|
|||
|
foreach($file in $copyFiles)
|
|||
|
{
|
|||
|
$srcFile = Join-Path $srcPath $file
|
|||
|
$dstFile = Join-Path $dstPath $file
|
|||
|
|
|||
|
if(!(Test-Path $dstFile))
|
|||
|
{
|
|||
|
Write-Verbose "$logLead File $dstFile doesn't exist. Creating."
|
|||
|
New-Item -ItemType File -Path $dstFile -Force | Out-Null
|
|||
|
}
|
|||
|
|
|||
|
Write-Verbose "$logLead Copying $file"
|
|||
|
Copy-Item $srcFile $dstFile -Force
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
$jobs = @()
|
|||
|
for($i = 0; $i -lt $numJobs; $i++)
|
|||
|
{
|
|||
|
$start = $i * $filesPerJob
|
|||
|
$end = ($i + 1) * $filesPerJob
|
|||
|
|
|||
|
if($start -ge $numFiles)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
elseif($end -gt ($numFiles - 1))
|
|||
|
{
|
|||
|
$end = ($numFiles - 1)
|
|||
|
}
|
|||
|
|
|||
|
$copyFiles = $filesToCopy[$start..$end]
|
|||
|
$jobs += Start-Job -ScriptBlock $scriptBlock -ArgumentList $srcPath, $dstPath, $copyFiles
|
|||
|
|
|||
|
$running = @($jobs | Where-Object {$_.State -in ('Running','NotStarted')})
|
|||
|
while ($running.Count -ge $maxJobs -and $running.Count -ne 0)
|
|||
|
{
|
|||
|
$finished = Wait-Job -Job $jobs -Any
|
|||
|
$running = @($jobs | Where-Object {$_.State -in ('Running','NotStarted')})
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
# Wait for all jobs in this session to complete.
|
|||
|
Get-Job | Wait-Job > $null
|
|||
|
|
|||
|
# Receive-Job to output the logs.
|
|||
|
$jobs | ForEach-Object { $_ | Receive-Job }
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Write-Host "$logLead No files to copy."
|
|||
|
}
|
|||
|
|
|||
|
if($delCount)
|
|||
|
{
|
|||
|
Write-Host "$logLead Starting file deletes."
|
|||
|
foreach($file in $filesToDelete)
|
|||
|
{
|
|||
|
$dstFile = Join-Path $dstPath $file
|
|||
|
if(test-path $dstFile)
|
|||
|
{
|
|||
|
Write-Verbose "$logLead Deleting $dstFile"
|
|||
|
Remove-Item -Path $dstFile -Force
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Write-Host "$logLead No files to delete."
|
|||
|
}
|
|||
|
|
|||
|
Write-Host "`n$logLead Writing file manifest to $manifestPath"
|
|||
|
Set-Content -Force -Path $manifestPath -Value $srcFiles
|
|||
|
|
|||
|
# Write out leftover files that survived the release.
|
|||
|
Write-Host "`n$logLead Now determining leftover files that were untouched by the release copy in $dstPath"
|
|||
|
$dstFiles = (Get-RelativeFileList $dstPath)
|
|||
|
$leftoverFiles = Get-SetDifference $dstFiles $srcFiles
|
|||
|
|
|||
|
Write-Host "$logLead Writing leftover files to $manifestLeftoverPath"
|
|||
|
Set-Content -Force -Path $manifestLeftoverPath -Value $leftoverFiles
|
|||
|
|
|||
|
$symlinkPath = (Join-Path $dstPath "createSymlinks.ps1")
|
|||
|
if (Test-Path $symlinkPath)
|
|||
|
{
|
|||
|
Write-Output "$logLead Running Symlink script."
|
|||
|
& $symlinkPath
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Write-Warning ("$logLead Symlink script not found at `"$symlinkPath`"")
|
|||
|
}
|
|||
|
|
|||
|
$timer.Stop();
|
|||
|
Write-Host ("`n$logLead Alkami Manifest Release Copy finished in [{0}]" -f $timer.Elapsed.ToString())
|
|||
|
}
|