Modules/businessdev.ALbuild.Apps/Private/Get-BcAlObjectMap.ps1
|
function Get-BcAlObjectMap { <# .SYNOPSIS Maps AL object identity (type + id) to its source file by scanning a workspace's .al files. .DESCRIPTION Reads the first object declaration in each .al file (e.g. `codeunit 50100 "My Codeunit"`) and returns a hashtable keyed "<Type>:<Id>" -> { Type; Id; Name; File }. Used to attach BC code coverage rows (which carry only object type + id) to source files. Skips symbol/output/tooling folders (relative to the root), like Get-BcProjectBuildOrder. #> [CmdletBinding()] [OutputType([hashtable])] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $WorkspaceRoot ) $root = (Resolve-Path -LiteralPath $WorkspaceRoot).Path $map = @{} # First object declaration: <type> <id> <name> ; name may be quoted or bare. $rx = [regex]::new( '(?im)^\s*(codeunit|table|page|report|xmlport|query|enum|controladdin|pageextension|tableextension|reportextension|enumextension|permissionset|permissionsetextension|profile|interface|entitlement|dotnet)\s+(\d+)\s+("(?<q>[^"]+)"|(?<b>[A-Za-z0-9_]+))') foreach ($file in Get-ChildItem -LiteralPath $root -Filter '*.al' -File -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.FullName.Substring($root.Length) -notmatch '[\\/](\.alpackages|\.altemplates|\.snapshots|\.output|output|\.git|\.claude|node_modules)[\\/]' }) { $text = Get-Content -LiteralPath $file.FullName -Raw -ErrorAction SilentlyContinue if (-not $text) { continue } $m = $rx.Match($text) if (-not $m.Success) { continue } $type = (Get-Culture).TextInfo.ToTitleCase($m.Groups[1].Value.ToLowerInvariant()) $id = [int]$m.Groups[2].Value $name = if ($m.Groups['q'].Success) { $m.Groups['q'].Value } else { $m.Groups['b'].Value } $map["$type`:$id"] = [PSCustomObject]@{ Type = $type; Id = $id; Name = $name; File = $file.FullName } } return $map } |