Modules/businessdev.ALbuild.Feeds/Public/Get-BcDependencyReconciliation.ps1
|
function Get-BcDependencyReconciliation { <# .SYNOPSIS Reconciles an app's manifest dependencies against what a container already has and what the configured feeds can provide. .DESCRIPTION Read-only (installs nothing). For each dependency (from app.json 'dependencies'), reports whether it is already satisfied by an app installed in the container, otherwise whether a configured feed can provide a compatible version, otherwise that it is missing. Microsoft first-party apps ship with the artifact, so they normally show up as satisfied by the container. Feeds are taken from -Feeds, else the currently registered feeds (Get-BcFeed) -- register them first with Register-BcFeed / Register-BcFeed -FromProjectConfig. .PARAMETER ContainerName The container to reconcile against. .PARAMETER Dependencies The app.json 'dependencies' entries: objects with id (GUID), optional name/publisher, and version (the minimum required version). .PARAMETER Feeds Feed definitions to search (default: all currently registered feeds). .OUTPUTS PSCustomObject: containerName, feedsSearched, summary { total, satisfied, availableFromFeed, missing }, satisfied[], availableFromFeed[], missing[]. #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $ContainerName, [Parameter(Mandatory)] [AllowEmptyCollection()] [object[]] $Dependencies, [object[]] $Feeds ) $feedList = if ($Feeds) { @($Feeds) } else { @(Get-BcFeed) } $installed = @(Get-BcContainerAppInfo -Name $ContainerName) $satisfied = [System.Collections.Generic.List[object]]::new() $available = [System.Collections.Generic.List[object]]::new() $missing = [System.Collections.Generic.List[object]]::new() foreach ($d in @($Dependencies)) { $appId = if ($d.PSObject.Properties.Name -contains 'id' -and $d.id) { "$($d.id)" } elseif ($d.PSObject.Properties.Name -contains 'appId' -and $d.appId) { "$($d.appId)" } else { '' } $req = "$($d.version)" $name = "$($d.name)"; $publisher = "$($d.publisher)" $inst = $installed | Where-Object { "$($_.AppId)" -eq $appId } | Select-Object -First 1 $instOk = $false if ($inst) { try { $instOk = ([version]"$($inst.Version)" -ge [version]$req) } catch { $instOk = $true } } if ($instOk) { $satisfied.Add([PSCustomObject]@{ appId = $appId; name = $name; version = "$($inst.Version)"; source = 'container' }) continue } $found = @() if ($feedList.Count -gt 0 -and $appId) { try { $found = @(Find-BcPackage -AppId $appId -Name $name -Publisher $publisher -Feeds $feedList) } catch { $found = @() } } $ok = @($found | Where-Object { try { [version]"$($_.Version)" -ge [version]$req } catch { $false } }) if ($ok.Count -gt 0) { $best = $ok | Sort-Object { [version]"$($_.Version)" } -Descending | Select-Object -First 1 $available.Add([PSCustomObject]@{ appId = $appId; name = $name; requiredVersion = $req feed = $best.Feed; packageId = $best.PackageId; bestVersion = "$($best.Version)" availableVersions = @($ok | ForEach-Object { "$($_.Version)" }) }) } else { $reason = if ($inst) { "Installed version $($inst.Version) is below required $req and no feed has a newer one" } else { 'Not in container and not found in any configured feed' } $missing.Add([PSCustomObject]@{ appId = $appId; name = $name; publisher = $publisher; requiredVersion = $req installedVersion = "$($inst.Version)"; reason = $reason; action = 'Provide via publish-app / deps install' }) } } return [PSCustomObject]@{ containerName = $ContainerName feedsSearched = @($feedList | ForEach-Object { $_.Name }) summary = [PSCustomObject]@{ total = @($Dependencies).Count; satisfied = $satisfied.Count; availableFromFeed = $available.Count; missing = $missing.Count } satisfied = @($satisfied) availableFromFeed = @($available) missing = @($missing) } } |