diff --git a/build.ps1 b/build.ps1 index 0fc4e59..9ff38bf 100644 --- a/build.ps1 +++ b/build.ps1 @@ -4,18 +4,51 @@ param( [string]$GitCodeGuiRepository = 'lzt404/EasyCLIProxyAPI', - [string]$GitCodeCoreRepository = 'lzt404/CLIProxyAPI' + [string]$GitCodeCoreRepository = 'lzt404/CLIProxyAPI', + + [switch]$SkipCopy ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $RootDir = $PSScriptRoot -$AppBin = Join-Path $RootDir 'src-tauri\target\release\cpa-gui.exe' +$TargetDir = Join-Path $RootDir 'src-tauri\target' +$BuildRootMarker = Join-Path $TargetDir '.build-workspace-root' +$AppBin = Join-Path $TargetDir 'release\cpa-gui.exe' $CopyScript = Join-Path $RootDir 'copy.ps1' Set-Location -LiteralPath $RootDir +function Test-StaleTauriBuildCache { + param([string]$BuildDir, [string]$TargetDir) + + if (-not (Test-Path -LiteralPath $BuildDir -PathType Container)) { + return $false + } + + $TargetPrefix = $TargetDir.TrimEnd('\', '/') + [IO.Path]::DirectorySeparatorChar + foreach ($directory in Get-ChildItem -LiteralPath $BuildDir -Directory -Filter 'tauri-*') { + $output = Join-Path $directory.FullName 'output' + if (-not (Test-Path -LiteralPath $output -PathType Leaf)) { + continue + } + foreach ($line in [IO.File]::ReadLines($output)) { + $marker = 'PERMISSION_FILES_PATH=' + $position = $line.IndexOf($marker, [StringComparison]::Ordinal) + if ($position -lt 0) { + continue + } + $permissionPath = $line.Substring($position + $marker.Length).Trim() + if (-not $permissionPath.StartsWith($TargetPrefix, [StringComparison]::OrdinalIgnoreCase) -or + -not (Test-Path -LiteralPath $permissionPath)) { + return $true + } + } + } + return $false +} + if (-not $PSBoundParameters.ContainsKey('BuildJobs')) { $BuildJobs = if ($env:CARGO_BUILD_JOBS) { [int]$env:CARGO_BUILD_JOBS @@ -42,24 +75,62 @@ Write-Host "Cargo build jobs: $BuildJobs" Write-Host "GitCode GUI fallback repository: $GitCodeGuiRepository" Write-Host "GitCode core fallback repository: $GitCodeCoreRepository" +$CachedRoot = if (Test-Path -LiteralPath $BuildRootMarker -PathType Leaf) { + (Get-Content -LiteralPath $BuildRootMarker -Raw).Trim() +} +else { + '' +} +if (-not $CachedRoot.Equals($RootDir, [StringComparison]::OrdinalIgnoreCase) -and + (Test-StaleTauriBuildCache -BuildDir (Join-Path $TargetDir 'release\build') -TargetDir $TargetDir)) { + $ExpectedTargetDir = [IO.Path]::GetFullPath((Join-Path $RootDir 'src-tauri\target')) + $ResolvedTargetDir = (Resolve-Path -LiteralPath $TargetDir).Path + if (-not $ResolvedTargetDir.Equals($ExpectedTargetDir, [StringComparison]::OrdinalIgnoreCase)) { + throw "Refusing to clean an unexpected Cargo target directory: $ResolvedTargetDir" + } + if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) { + throw 'cargo is required to refresh the stale Tauri build cache.' + } + Write-Host 'Tauri release cache references a previous workspace path; rebuilding its generated permissions.' + for ($attempt = 1; $attempt -le 3; $attempt++) { + & cargo clean --manifest-path (Join-Path $RootDir 'src-tauri\Cargo.toml') --target-dir $TargetDir -p tauri --release + if ($LASTEXITCODE -eq 0) { + break + } + if ($attempt -eq 3) { + throw "Failed to refresh the Tauri release cache (exit code $LASTEXITCODE)." + } + Start-Sleep -Seconds $attempt + } +} + & bun install if ($LASTEXITCODE -ne 0) { throw "bun install failed with exit code $LASTEXITCODE." } $PreviousBuildJobs = $env:CARGO_BUILD_JOBS +$PreviousCargoTargetDir = $env:CARGO_TARGET_DIR $PreviousGitCodeGuiRepository = $env:GITCODE_GUI_REPOSITORY $PreviousGitCodeCoreRepository = $env:GITCODE_CORE_REPOSITORY try { $env:CARGO_BUILD_JOBS = [string]$BuildJobs + $env:CARGO_TARGET_DIR = $TargetDir $env:GITCODE_GUI_REPOSITORY = $GitCodeGuiRepository $env:GITCODE_CORE_REPOSITORY = $GitCodeCoreRepository & bun tauri build --no-bundle if ($LASTEXITCODE -ne 0) { throw "Tauri build failed with exit code $LASTEXITCODE." } + [IO.File]::WriteAllText($BuildRootMarker, $RootDir, [Text.UTF8Encoding]::new($false)) } finally { + if ($null -eq $PreviousCargoTargetDir) { + Remove-Item Env:CARGO_TARGET_DIR -ErrorAction SilentlyContinue + } + else { + $env:CARGO_TARGET_DIR = $PreviousCargoTargetDir + } if ($null -eq $PreviousBuildJobs) { Remove-Item Env:CARGO_BUILD_JOBS -ErrorAction SilentlyContinue } @@ -85,4 +156,9 @@ if (-not (Test-Path -LiteralPath $AppBin -PathType Leaf)) { } Write-Host "Built: $AppBin" -& $CopyScript +if ($SkipCopy) { + Write-Host 'Portable copy skipped; run .\copy.ps1 after closing the running app.' +} +else { + & $CopyScript +}