diff --git a/ue-updatelyra.ps1 b/ue-updatelyra.ps1 new file mode 100644 index 0000000..f747c35 --- /dev/null +++ b/ue-updatelyra.ps1 @@ -0,0 +1,257 @@ +[CmdletBinding()] # Fail on unknown args +param ( + [string]$src, + [string]$dest, + [string]$mainbranch = "main", + [string]$upstreambranch = "lyra-upstream", + [string]$custombranch = "lyra-custom", + [switch]$dryrun = $false, + [switch]$help = $false +) + +function Print-Usage { + Write-Output "Steve's Lyra Update Tool" + Write-Output "Usage:" + Write-Output " ue-updatelyra.ps1 [-src:]sourcefolder [-dest:destfolder] [Options]" + Write-Output " " + Write-Output " -src : Source Lyra folder" + Write-Output " : Folder created by Create Project on Lyra in Marketplace" + Write-Output " -dest : Destination folder (default: current directory)" + Write-Output " : Must be root folder of your custom Lyra based project" + Write-Output " -mainbranch : Name of main branch (default main)" + Write-Output " -upstreambranch : Name of branch containing pristine upstream version of Lyra (default lyra-upstream)" + Write-Output " : (MUST exist! We need to know where the pristine Lyra goes)" + Write-Output " -custombranch : Name of branch with your custom changes to Lyra (default lyra-custom)" + Write-Output " : (Will be created if missing)" + Write-Output " -dryrun : Don't perform any actual actions, just report on what you would do" + Write-Output " -help : Print this help" + Write-Output " " + +} + +$ErrorActionPreference = "Stop" + +if ($help) { + Print-Usage + Exit 0 +} + +if ($src.Length -eq 0) { + Write-Output "Error: Source directory argument is mandatory" + Print-Usage + Exit 3 +} + +if ($dest.Length -eq 0) { + $dest = "." + Write-Verbose "dest not specified, assuming current directory" +} + +# Detect Git +if ($dest -ne ".") { Push-Location $dest } +$isGit = Test-Path ".git" +if ($dest -ne ".") { Pop-Location } + +if (-not $isGit) +{ + Write-Output "Destination '$dest' is not a Git repo, cannot continue!" + Exit 3 +} +# Check that source contains Lyra +if (-not (Test-Path (Join-Path $src "LyraStarterGame.uproject"))) +{ + Write-Output "Source folder '$src' does not contain LyraStarterGame.uproject" + Exit 3 +} +# Check that destination contains Lyra +if (-not (Test-Path (Join-Path $dest "LyraStarterGame.uproject"))) +{ + Write-Output "Destination folder '$dest' does not contain LyraStarterGame.uproject" + Exit 3 +} +# Check that source & destination are not the same (no standardise path in ps, Join-Path does it) +if ((Join-Path (Resolve-Path $dest) "") -eq (Join-Path (Resolve-Path $src) "")) +{ + Write-Output "Source and destination folder point to the same location, $src" + Exit 3 +} + +# Check working copy is clean +if ($dest -ne ".") { Push-Location $dest } + +if (Test-Path ".git") { + git diff --no-patch --exit-code + if ($LASTEXITCODE -ne 0) { + Write-Output "Working copy is not clean (unstaged changes)" + if ($dryrun) { + Write-Output "dryrun: Continuing but this will fail without -dryrun" + } else { + Exit $LASTEXITCODE + } + } + git diff --no-patch --cached --exit-code + if ($LASTEXITCODE -ne 0) { + Write-Output "Working copy is not clean (staged changes)" + if ($dryrun) { + Write-Output "dryrun: Continuing but this will fail without -dryrun" + } else { + Exit $LASTEXITCODE + } + } +} + + +git rev-parse --verify -q $upstreambranch > $null +if ($LASTEXITCODE -ne 0) +{ + Write-Output "Missing Lyra upstream branch '$upstreambranch'" + Exit 3 +} +git rev-parse --verify -q $mainbranch > $null +if ($LASTEXITCODE -ne 0) +{ + Write-Output "Missing main branch '$mainbranch'" + Exit 3 +} + + +if ($dryrun) +{ + Write-Output "Would have run:" +} + +# Switch to lyra pristine branch +if ($dryrun) +{ + Write-Output " > git checkout $upstreambranch" +} +else +{ + git checkout $upstreambranch +} + +# Check that dest contains Lyra +if (-not (Test-Path (Join-Path $dest "LyraStarterGame.uproject"))) +{ + Write-Output "Destination folder '$dest' does not contain LyraStarterGame.uproject after checking out $upstreambranch" + Exit 3 +} + +try { + # Copy Lyra source + # Use robocopy -mir so that we delete files that are missing in source + + $argList = [System.Collections.ArrayList]@() + $argList.Add($src) > $null + $argList.Add($dest) > $null + # Mirror (deletes) + $argList.Add("/mir") > $null + # Allow resume + $argList.Add("/z") > $null + # Wait time for retry + $argList.Add("/w:3") > $null + # Exclude git files / dirs (do not delete because of mirroring) + $argList.Add("/xf") > $null + $argList.Add((Join-Path $dest ".gitignore")) > $null + $argList.Add("/xf") > $null + $argList.Add((Join-Path $dest ".gitattributes")) > $null + $argList.Add("/xf") > $null + $argList.Add((Join-Path $dest ".gitmodules")) > $null + $argList.Add("/xd") > $null + $argList.Add((Join-Path $dest ".git")) > $null + # Exclude source Intermediate, Binaries, DDC + $argList.Add("/xd") > $null + $argList.Add((Join-Path $src "Binaries")) > $null + $argList.Add("/xd") > $null + $argList.Add((Join-Path $src "Intermediate")) > $null + $argList.Add("/xd") > $null + $argList.Add((Join-Path $src "DerivedDataCache")) > $null + + if ($dryrun) { + Write-Output " > robocopy $($argList -join " ")" + + } else { + $proc = Start-Process "robocopy" $argList -Wait -PassThru -NoNewWindow + # Robocopy can return up to value 8 for success + # See https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy + if ($proc.ExitCode -gt 8) { + throw "robocopy failed!" + } + } + + + # Add & Commit changes, if any + if (-not $dryrun) + { + git add . + git diff --no-patch --cached --exit-code + if ($LASTEXITCODE -eq 0) { + Write-Output "No changes found to Lyra" + git checkout $mainbranch + Exit 0 + } + git commit -m "Lyra update" + } + else + { + Write-Output " > git add . && git commit -m `"Lyra update`"" + } + + + if (-not $dryrun) + { + # Merge changes into custom + git rev-parse --verify -q $custombranch > $null + if ($LASTEXITCODE -ne 0) + { + Write-Output "Creating branch '$custombranch'" + git checkout -b $custombranch + } + else + { + git checkout $custombranch + git merge $upstreambranch + if ($LASTEXITCODE -ne 0) + { + throw "Unable to merge $upstreambranch into $custombranch, resolve merge conflicts and finish merge into $mainbranch yourself " + } + } + + # merge changes into main branch + git checkout $mainbranch + git merge $custombranch + if ($LASTEXITCODE -ne 0) + { + throw "Unable to merge $upstreambranch into $custombranch, resolve merge conflicts and finish merge into $mainbranch yourself " + } + + + } + else + { + Write-Output " > git checkout $custombranch" + Write-Output " > git merge $upstreambranch" + Write-Output " > git checkout $mainbranch" + Write-Output " > git merge $custombranch" + + } + + + +} +catch { + if ($dest -ne ".") { Pop-Location } + Write-Output $_.Exception.Message + Write-Output "~-~-~ Updating Lyra FAILED ~-~-~" + Exit 9 +} + +if ($dest -ne ".") { Pop-Location } +Write-Output "~-~-~ Lyra Update Completed OK ~-~-~" + + + + + + +