param( [string]$SourceRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path, [string]$DestinationRoot = "Q:\home\thomas\TuxDMXWebUI", [string]$StageRoot = (Join-Path $env:USERPROFILE "Desktop\TuxDMXWebUI-update"), [switch]$PackageOnly, [switch]$DryRun ) Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" function Write-Info { param([string]$Message) Write-Host "[TuxDMX] $Message" } function Invoke-Robocopy { param( [string]$Source, [string]$Destination, [string[]]$ExtraArguments = @() ) $arguments = @( $Source, $Destination, "/E", "/R:2", "/W:1", "/FFT", "/XJ", "/NP", "/NDL" ) + $ExtraArguments if ($DryRun) { $arguments += "/L" } Write-Info ("robocopy " + ($arguments -join " ")) & robocopy @arguments $exitCode = $LASTEXITCODE if ($exitCode -ge 8) { throw "Robocopy fejlede med exit code $exitCode." } } function Reset-Directory { param([string]$Path) if (Test-Path $Path) { Remove-Item -LiteralPath $Path -Recurse -Force } New-Item -ItemType Directory -Force -Path $Path | Out-Null } $resolvedSource = (Resolve-Path $SourceRoot).Path if (-not (Test-Path $resolvedSource)) { throw "Kildemappen findes ikke: $SourceRoot" } $excludedDirectories = @( ".git", ".github", ".venv", ".mypy_cache", ".pnpm-store", ".pytest_cache", ".ruff_cache", "node_modules", "data", "__pycache__" ) $excludedFiles = @( "*.pyc", "*.pyo", "*.log" ) $extraArguments = @() if ($excludedDirectories.Count -gt 0) { $extraArguments += "/XD" $extraArguments += $excludedDirectories } if ($excludedFiles.Count -gt 0) { $extraArguments += "/XF" $extraArguments += $excludedFiles } Write-Info "Kilde: $resolvedSource" Write-Info "Maal: $DestinationRoot" Write-Info "Ekskluderer data, dependencies, caches og git-metadata." Write-Info "Fallback-pakke: $StageRoot" $syncFailed = $false if (-not $PackageOnly) { if (-not (Test-Path $DestinationRoot)) { Write-Info "Maalmappe findes ikke, opretter: $DestinationRoot" New-Item -ItemType Directory -Force -Path $DestinationRoot | Out-Null } try { Invoke-Robocopy -Source $resolvedSource -Destination $DestinationRoot -ExtraArguments $extraArguments } catch { $syncFailed = $true Write-Info "Direkte sync til share fejlede: $($_.Exception.Message)" Write-Info "Bygger i stedet en lokal update-pakke med de deploy-klare filer." } } $distSource = Join-Path $resolvedSource "frontend\dist" if (-not (Test-Path $distSource)) { Write-Info "Advarsel: frontend/dist findes ikke endnu. Koer frontend build foer deployment, hvis UI-assets skal med." } if ($PackageOnly -or $syncFailed) { if (-not $DryRun) { Reset-Directory -Path $StageRoot } Invoke-Robocopy -Source $resolvedSource -Destination $StageRoot -ExtraArguments $extraArguments if ($DryRun) { Write-Info "Dry-run af lokal update-pakke afsluttet uden at skrive filer." } else { Write-Info "Lokal update-pakke er klar: $StageRoot" Write-Info "Kopier indholdet herfra over paa Linux-maskinen med de rettigheder du har." } } elseif ($DryRun) { Write-Info "Dry-run afsluttet uden at skrive filer." } else { Write-Info "Synk afsluttet direkte til share." }