functions/Resolve-ExtensionDuplicates.ps1
|
# <copyright file="Resolve-ExtensionDuplicates.ps1" company="Endjin Limited"> # Copyright (c) Endjin Limited. All rights reserved. # </copyright> function Resolve-ExtensionDuplicates { <# .SYNOPSIS Removes duplicate extension references, keeping the first one found. .DESCRIPTION It is common for a low-level extension to be referenced by more than one higher-level extension (e.g. as a shared dependency). When the resolved extension list contains multiple references to the same extension 'Name', this function removes the duplicates, keeping the first one found. A warning is only logged when the duplicate references resolve to genuinely different versions. The reliable indicator of the resolved version across all extension types (Git, PowerShell repository and local path) is the 'Path' property, which encodes the version or git ref as part of the on-disk folder structure. Duplicates that resolve to the same 'Path' are the same version and are de-duplicated silently. .PARAMETER Extensions The array of resolved extensions (as returned by Register-Extensions) to de-duplicate. .EXAMPLE PS:> $deduplicated = Resolve-ExtensionDuplicates -Extensions $resolvedExtensions Removes duplicate references from the resolved extension list (keeping the first one found), warning only where the duplicates resolve to genuinely different versions. #> [CmdletBinding()] [OutputType([hashtable])] param ( [Parameter(Mandatory)] [AllowEmptyCollection()] [hashtable[]] $Extensions ) $groupedByName = $Extensions | Group-Object -Property Name # Warn only when the same extension has been resolved to more than one distinct # location (i.e. a genuine version conflict), rather than for every shared reference. $groupedByName | Where-Object { $_.Count -gt 1 -and ($_.Group.Path | Select-Object -Unique).Count -gt 1 } | ForEach-Object { $winner = $_.Group | Select-Object -First 1 $ignored = $_.Group | Select-Object -Skip 1 $conflicts = $_.Group | Select-Object Name, Version, Path Write-Warning ("Multiple versions of extension '$($_.Name)' have been resolved - " + "using the first one found and ignoring the rest:`n" + "Using: $($winner.Path)`n" + "Ignored: $($ignored.Path -join ', ')`n" + "$($conflicts | ConvertTo-Json)") } # De-duplicate by Name, keeping the first one found (preserves the existing # depth-first resolution order, so the top-most consumer wins). [hashtable[]] $deduplicated = $groupedByName | ForEach-Object { $_.Group | Select-Object -First 1 } return $deduplicated } |