Private/Find-GitHubDumpPair.ps1
|
# Copyright (c) 2026 Jeffrey Snover. All rights reserved. # Licensed under the MIT License. See LICENSE file in the project root. # Pair-discovery helper for Get-AzureFlightRecorder -Merged (t/1377). # Extracted to Private/ so the two-scheme + orphan matrix is directly unit-testable # without mocking gh / GitHub / Merge-FlightRecorderDumps. <# .SYNOPSIS Resolves the client + server flight-recorder dump pair for a DumpId across both naming schemes present in the data repo. .DESCRIPTION - Paired (preferred): client-{DumpId}.jsonl + server-{DumpId}.jsonl - Legacy: flight-recorder-{DumpId}.jsonl + server-flight-recorder-{DumpId}.jsonl Returns a PSCustomObject with { DumpId, Scheme, Client, Server }. Either Client or Server may be $null (orphan) — Merge-FlightRecorderDumps handles single-side merges gracefully, so this helper never throws for orphans. Prefers paired-scheme when EITHER side matches; falls back to legacy otherwise. If both schemes are absent, returns Client=$null, Server=$null. .PARAMETER DumpId Correlation ID (e.g. 'a1b2c3d4' or a timestamp string). .PARAMETER Files Enumerable of file descriptor objects, each having a `.name` property (the same shape produced by Get-GitHubDumpList / gh api contents). #> function Find-GitHubDumpPair { [CmdletBinding()] param( [Parameter(Mandatory)][string]$DumpId, [Parameter()][object]$Files ) # Strict-mode .Count guard — @()-wrap every Where-Object pipeline # (TL condition p/174#1). Also filter out null entries: @($null) is a # 1-element array containing $null, which trips strict-mode property # access inside Where-Object even before .Count is read. $items = @($Files) | Where-Object { $null -ne $_ } $items = @($items) $escaped = [regex]::Escape($DumpId) # Paired-scheme match $pairedClient = @($items | Where-Object { $_.name -eq "client-$DumpId.jsonl" }) $pairedServer = @($items | Where-Object { $_.name -eq "server-$DumpId.jsonl" }) # Legacy-scheme match — anchored with ^...$ so server- doesn't leak to client. $legacyClient = @($items | Where-Object { $_.name -match "^flight-recorder-$escaped\.jsonl$" }) $legacyServer = @($items | Where-Object { $_.name -match "^server-flight-recorder-$escaped\.jsonl$" }) $scheme = if (@($pairedClient).Count -gt 0 -or @($pairedServer).Count -gt 0) { 'paired' } else { 'legacy' } $clientMatch = if ($scheme -eq 'paired' -and @($pairedClient).Count -gt 0) { $pairedClient[0] } elseif ($scheme -eq 'legacy' -and @($legacyClient).Count -gt 0) { $legacyClient[0] } else { $null } $serverMatch = if ($scheme -eq 'paired' -and @($pairedServer).Count -gt 0) { $pairedServer[0] } elseif ($scheme -eq 'legacy' -and @($legacyServer).Count -gt 0) { $legacyServer[0] } else { $null } [PSCustomObject]@{ DumpId = $DumpId Scheme = $scheme Client = $clientMatch Server = $serverMatch } } |