src/_Install-CciModuleFromBlob.ps1
|
function _Install-CciModuleFromBlob { <# .SYNOPSIS Installs a module (and its RequiredModules, recursively) from the tenant distribution store. .DESCRIPTION The feed path gets dependency resolution for free from PSResourceGet; the store path has to do it explicitly, by reading RequiredModules from the installed manifest and fetching each dependency that is not already available. $Seen guards against cycles and repeat work. #> [CmdletBinding()] param( [Parameter(Mandatory)][string]$Name, [Parameter(Mandatory)]$Feed, [Parameter(Mandatory)]$Context, [Parameter(Mandatory)]$Index, [string]$Version, [ValidateSet('CurrentUser','AllUsers')][string]$Scope = 'CurrentUser', [switch]$Reinstall, [System.Collections.Generic.HashSet[string]]$Seen ) if (-not $Seen) { $Seen = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase) } if (-not $Seen.Add($Name)) { return } $entry = $Index.modules.PSObject.Properties[$Name] if (-not $entry) { throw "cciget: '$Name' is not present in the tenant distribution store index." } if (-not $Version) { $Version = $entry.Value.latest } $root = _Get-CciModulesRoot -Scope $Scope $target = Join-Path (Join-Path $root $Name) $Version if ((Test-Path $target) -and -not $Reinstall) { Write-Host "cciget: $Name $Version already installed." } else { New-Item -ItemType Directory -Path $target -Force | Out-Null $prefix = "$($Feed.blobPrefix)/$Name/$Version/" $blobs = @(Get-AzStorageBlob -Context $Context -Container $Feed.blobContainer -Prefix $prefix -ErrorAction Stop) if (-not $blobs) { throw "cciget: no content under '$prefix' in the distribution store." } Write-Host "cciget: downloading $Name $Version ($($blobs.Count) files) from the tenant distribution store..." foreach ($b in $blobs) { $rel = $b.Name.Substring($prefix.Length) if (-not $rel) { continue } $dest = Join-Path $target ($rel -replace '/', '\') $dir = Split-Path $dest -Parent if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } $null = Get-AzStorageBlobContent -Context $Context -Container $Feed.blobContainer ` -Blob $b.Name -Destination $dest -Force -ErrorAction Stop } Write-Host "cciget: installed $Name $Version -> $target" } $psd1 = Get-ChildItem $target -Filter '*.psd1' | Select-Object -First 1 if ($psd1) { $manifest = Import-PowerShellDataFile $psd1.FullName foreach ($dep in @($manifest.RequiredModules)) { if (-not $dep) { continue } $depName = if ($dep -is [hashtable]) { $dep.ModuleName } else { "$dep" } if (-not $depName) { continue } if (Get-Module -ListAvailable -Name $depName) { Write-Verbose "cciget: dependency $depName already available." continue } Write-Host "cciget: resolving dependency $depName..." _Install-CciModuleFromBlob -Name $depName -Feed $Feed -Context $Context -Index $Index ` -Scope $Scope -Reinstall:$Reinstall -Seen $Seen } } } |