Private/Show-Win32ToolkitDependencyPicker.ps1
|
function Show-Win32ToolkitDependencyPicker { <# .SYNOPSIS Spectre picker for declaring app dependencies — choose from winget or an already-packaged project. .DESCRIPTION Returns the chosen dependencies as reference STRINGS ('winget:<id>' / 'project:<Template>\<Name>'), ready to hand to Set-Win32ToolkitAppDependency or -DependsOn. Purely a chooser: it declares nothing and installs nothing. Used by the packaging wizards ("does this app need something installed first?" — e.g. a Visual C++ redistributable) and by the project-actions dependency editor. .PARAMETER BasePath Base folder, used to list already-packaged projects. .PARAMETER Existing References already declared, shown so the operator can see what is set and does not re-add it. .OUTPUTS [string[]] the FULL dependency reference list (existing + newly chosen). Empty array if none. #> [CmdletBinding()] [OutputType([string[]])] param( [string]$BasePath, [string[]]$Existing = @() ) $refs = [System.Collections.Generic.List[string]]::new() foreach ($e in @($Existing)) { if ($e) { $refs.Add([string]$e) } } while ($true) { Write-SpectreHost '' if ($refs.Count -gt 0) { Write-SpectreHost "[grey]Dependencies (installed BEFORE this app):[/] $(Get-SpectreEscapedText -Text ($refs -join ', '))" } else { Write-SpectreHost '[grey]No dependencies declared — this app installs on its own.[/]' } $choices = @( [pscustomobject]@{ Key = 'winget'; Label = 'Add a dependency from winget (e.g. the VC++ redistributable)' } [pscustomobject]@{ Key = 'project'; Label = 'Add a dependency from an already-packaged project' } [pscustomobject]@{ Key = 'intune'; Label = 'Pick an app already published in Intune (you will sign in)' } ) if ($refs.Count -gt 0) { $choices += [pscustomobject]@{ Key = 'remove'; Label = 'Remove a dependency' } } $choices += [pscustomobject]@{ Key = 'done'; Label = 'Done' } $sel = Read-SpectreSelection -Message 'Dependencies' -Choices $choices -ChoiceLabelProperty 'Label' -Color Blue switch ($sel.Key) { 'winget' { $term = Read-SpectreText -Message 'Search winget for the dependency (blank to cancel)' -DefaultAnswer '' if ([string]::IsNullOrWhiteSpace($term)) { break } $hits = @(Search-WingetApps -SearchTerm $term) if ($hits.Count -eq 0) { Write-SpectreHost "[yellow]No winget results for[/] $(Get-SpectreEscapedText -Text $term)." break } $pick = Read-SpectreSelection -Message 'Which package?' -Choices @( $hits | ForEach-Object { [pscustomobject]@{ Key = $_.Id; Label = "$($_.Name) [grey]($($_.Id))[/]" } } ) -ChoiceLabelProperty 'Label' -Color Blue -PageSize 12 # Store the winget ID VERBATIM — ids legitimately contain '.' and '+'. $ref = "winget:$($pick.Key)" if ($refs -notcontains $ref) { $refs.Add($ref) } } 'project' { $projects = @(Get-PSADTProjects -BasePath $BasePath) if ($projects.Count -eq 0) { Write-SpectreHost '[yellow]No packaged projects found yet — package the dependency first, or pick it from winget.[/]' break } $pick = Read-SpectreSelection -Message 'Which packaged project?' -Choices @( $projects | ForEach-Object { [pscustomobject]@{ Key = "$($_.Template)\$($_.Name)"; Label = "$($_.Name) [grey]($($_.Template))[/]" } } ) -ChoiceLabelProperty 'Label' -Color Blue -PageSize 12 $ref = "project:$($pick.Key)" if ($refs -notcontains $ref) { $refs.Add($ref) } } 'intune' { # Live tenant list. Stored as 'intune:<guid>' — an app id needs no resolution at publish # time. NOTE: an intune: dependency cannot be STAGED into the test guest (the toolkit has # no package for it), so the test run will not install it — the picker says so. try { Write-SpectreHost '[grey]Signing in to Intune to list published Win32 apps...[/]' Connect-Win32ToolkitGraph $apps = @(Find-Win32ToolkitIntuneApp -All) } catch { Write-SpectreHost "[red]Could not list Intune apps: $(Get-SpectreEscapedText -Text $_.Exception.Message)[/]" break } if ($apps.Count -eq 0) { Write-SpectreHost '[yellow]No Win32 apps found in the tenant.[/]'; break } # NOTE: displayVersion is NOT selectable here — /mobileApps is a collection of the BASE type # microsoft.graph.mobileApp, which has no such property (isof() filters, it does not cast). # So the label shows the publisher instead. $pick = Read-SpectreSelection -Message 'Which published app?' -Choices @( $apps | ForEach-Object { [pscustomobject]@{ Key = $_.Id; Label = "$($_.DisplayName) [grey]$($_.Publisher)[/]" } } ) -ChoiceLabelProperty 'Label' -Color Blue -PageSize 12 $ref = "intune:$($pick.Key)" if ($refs -notcontains $ref) { $refs.Add($ref) } Write-SpectreHost '[yellow]Note:[/] an Intune-picked app cannot be installed in the test/capture guest (no local package), so the test run will not have it. Use winget/project if you need it during testing.' } 'remove' { $pick = Read-SpectreSelection -Message 'Remove which dependency?' -Choices @( $refs | ForEach-Object { [pscustomobject]@{ Key = $_; Label = $_ } } ) -ChoiceLabelProperty 'Label' -Color Blue [void]$refs.Remove($pick.Key) } 'done' { return @($refs) } } } } |