Modules/businessdev.ALbuild.Containers/Public/Get-BcArtifactSymbolFolder.ps1
|
function Get-BcArtifactSymbolFolder { <# .SYNOPSIS Returns the symbol (package cache) folders a host AL compile needs from a downloaded BC artifact. .DESCRIPTION Collects every folder of a Get-BcArtifact result that provides compiled first-party symbols for a host (AL Tool) compile, in one place instead of each caller re-deriving the layout: * '<application>/Extensions' - first-party app symbols shipped with the country artifact. * '<application>/Applications.<COUNTRY>' - the compiled country apps INCLUDING the test toolkit (Tests-TestLibraries, Library Assert, Test Runner, ...). Localized artifacts only. * the platform folder holding 'System.app' - the AL system/runtime symbols. The W1 artifact ships no 'Applications.W1' folder - its compiled test toolkit lives scattered through the PLATFORM artifact instead ('Applications/TestFramework/**', 'Applications/BaseApp/Test', 'Applications/System Application/Test', ...). Without it, compiling a test app against W1 fails with AL1022 ('Tests-TestLibraries ... could not be found'). So when the country artifact has no 'Applications.*' folder, the platform's apps are staged once into '.albuild-toolkit-symbols' beside the platform artifact and that folder is returned too (keyed to the artifact version, so it is reused across builds): * W1 sandbox (an 'Extensions' folder IS present): only the test toolkit is missing - stage just those apps (paths matching 'TestFramework', a 'Test' segment, or a 'Test Library' name). * On-premises (NO 'Extensions' and NO 'Applications.<country>'): the platform 'Applications' tree is the only source of first-party symbols, so stage them ALL (the business apps Application / Base Application / Business Foundation under '<App>/Source', plus the toolkit), or the host compile fails with AL1022 for 'Microsoft Application' / 'Base Application'. .PARAMETER Artifact The artifact object returned by Get-BcArtifact (ApplicationPath / PlatformPath). .PARAMETER Force Re-stage the W1 toolkit symbols even when the staging folder already exists. .EXAMPLE $artifact = Get-BcArtifact -ArtifactUrl $url $symbols = Get-BcArtifactSymbolFolder -Artifact $artifact Invoke-BcCompiler -ProjectFolder .\app -PackageCachePath (@('.alpackages') + $symbols) .OUTPUTS System.String[] - existing folders, ready for the compiler's package cache path. #> [CmdletBinding()] [OutputType([string[]])] param( [Parameter(Mandatory)] [ValidateNotNull()] [object] $Artifact, [switch] $Force ) $paths = [System.Collections.Generic.List[string]]::new() $extensions = Join-Path $Artifact.ApplicationPath 'Extensions' $hasExtensions = Test-Path -LiteralPath $extensions if ($hasExtensions) { $paths.Add($extensions) } # Compiled, country-specific first-party apps incl. the test toolkit (localized artifacts only). $countryApps = @(Get-ChildItem -LiteralPath $Artifact.ApplicationPath -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -match '^Applications\..+' }) foreach ($folder in $countryApps) { $paths.Add($folder.FullName) } if ($Artifact.PlatformPath) { # The platform 'System.app' (AL system/runtime symbols) sits in a version-specific folder. $systemApp = Get-ChildItem -LiteralPath $Artifact.PlatformPath -Recurse -Filter 'System.app' -File -ErrorAction SilentlyContinue | Select-Object -First 1 if ($systemApp) { $paths.Add($systemApp.Directory.FullName) } # No 'Applications.<country>' folder: the compiled first-party apps the compiler needs live in # the platform 'Applications' tree instead - stage them once beside the platform artifact. # * W1 sandbox: the country artifact's 'Extensions' folder already provides the business apps # (Application, Base Application, ...); only the platform's test toolkit is missing, so stage # just that (TestFramework / a 'Test' segment / a 'Test Library' name). # * On-premises: there is no 'Extensions' (nor 'Applications.<country>') folder at all, so the # platform 'Applications' tree is the ONLY source of first-party symbols - stage every app # (the business apps under '<App>/Source' plus the test toolkit), or the compile fails with # AL1022 for 'Microsoft Application' / 'Base Application'. if ($countryApps.Count -eq 0) { $platformApps = Join-Path $Artifact.PlatformPath 'Applications' if (Test-Path -LiteralPath $platformApps) { $staging = Join-Path $Artifact.PlatformPath '.albuild-toolkit-symbols' # The staging folder is cached across builds, but its required CONTENT differs by mode: # 'toolkit' (W1 sandbox - test toolkit only) vs 'full' (on-prem - business apps + toolkit). # A folder staged in one mode must be re-staged for the other, so a plain "folder is not # empty" check is not enough - an older build (or a pre-fix module) may have staged only # the toolkit for what is really an on-prem artifact. Record the mode in a marker file and # re-stage when it is missing or does not match. $mode = if ($hasExtensions) { 'toolkit' } else { 'full' } $markerFile = Join-Path $staging '.albuild-symbols-mode' $currentMode = if (Test-Path -LiteralPath $markerFile) { "$(Get-Content -LiteralPath $markerFile -Raw -ErrorAction SilentlyContinue)".Trim() } else { '' } # Wrapped in @(): an if that emits an empty array collapses to $null via the pipeline, # and .Count on $null then dies under Set-StrictMode. $staged = @(if (Test-Path -LiteralPath $staging) { Get-ChildItem -LiteralPath $staging -Filter '*.app' -File -ErrorAction SilentlyContinue }) if ($Force -or $staged.Count -eq 0 -or $currentMode -ne $mode) { New-Item -ItemType Directory -Force -Path $staging | Out-Null $platformAppFiles = @(Get-ChildItem -LiteralPath $platformApps -Recurse -Filter '*.app' -File -ErrorAction SilentlyContinue) if ($hasExtensions) { $platformAppFiles = @($platformAppFiles | Where-Object { $_.FullName -match '(?i)[\\/]TestFramework[\\/]|[\\/]Test[\\/]|Test Library' }) } $platformAppFiles | Copy-Item -Destination $staging -Force Set-Content -LiteralPath $markerFile -Value $mode -Encoding UTF8 -NoNewline $what = if ($hasExtensions) { 'test toolkit' } else { 'first-party' } Write-ALbuildLog -Level Information "Staged the platform $what symbols ($($platformAppFiles.Count) app(s)) into '$staging'." } if (@(Get-ChildItem -LiteralPath $staging -Filter '*.app' -File -ErrorAction SilentlyContinue).Count -gt 0) { $paths.Add($staging) } } } } return $paths.ToArray() } |