winpack.psm1
$include = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition) . "$include\visuals.ps1" . "$include\classes.ps1" . "$include\tools.ps1" $script:fields = Get-Content $env:USERPROFILE\.config\.wingetposh\locals.json | ConvertFrom-Json [System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8 $env:GUM_CHOOSE_SELECTED_BACKGROUND = "22" $env:GUM_CHOOSE_SELECTED_FOREGROUND = "#ffffff" $sources = @{ "winget" = "winget" "scoop" = "scoop" } function Get-FieldBAseNAme { param( [string]$name ) $base = $script:fields.psobject.Properties | Where-Object { $_.Value -eq $name } if ($base.count -eq 1) { $BaseName = $base.Name } else { $BaseName = ($base | Where-Object { $_.Name.StartsWith("Search") }).Name } return $baseFields[$BaseName] } function Get-FieldLength { param( [string]$buffer ) $i = 0 $buffer.ToCharArray() | ForEach-Object { $l = [Text.Encoding]::UTF8.GetByteCount($_) if ($l -ge 2) { $l = $l - 1 } $i += $l } return $i } function Get-WGPackage { param( [string]$source = $null, [switch]$update = $false, [switch]$uninstall = $false ) $GetParams = @{} if ($source) { $GetParams.Add("source", $source) } if ($update -and $uninstall) { # TODO: make error message a generic function [System.Console]::setcursorposition(0, $Y) $Title = gum style " ERROR " --background $($Theme["red"]) --foreground $($Theme["white"]) --bold $buffer = gum style "$($Title)`n'-update' & '-uninstall' cannot be used at the same time" --border "rounded" --width ($Host.UI.RawUI.BufferSize.Width - 2) --foreground $($Theme["yellow"]) $buffer | ForEach-Object { [System.Console]::write($_) } return $null } $Session, $runspace = Open-Spinner -label "Loading Packages List" -type "Dots" $packages = Get-WinGetPackage if ($source) { $packages = $packages | Where-Object { $_.Source -eq $source } } if ($update) { $packages = $packages | Where-Object { $_.IsUpdateAvailable -eq $true } } # if ($interactive) { [column[]]$cols = @() $cols += [column]::new("Name", "Name", 40) $cols += [column]::new("Id", "Id", 40) $cols += [column]::new("InstalledVersion", "Version", 20) [package[]]$InstalledPackages = @() $packages | ForEach-Object { $InstalledPackages += [package]::new($_.Name, $_.Id, $_.AvailableVersions, $_.Source, $_.IsUpdateAvailable, $_.InstalledVersion) } $choices = makeLines -columns $cols -items $InstalledPackages $width = $Host.UI.RawUI.BufferSize.Width - 2 $height = $Host.UI.RawUI.BufferSize.Height - 7 $title = makeTitle -title "List of Installed Packages" -width $width $header = makeHeader -columns $cols Close-Spinner -session $Session -runspace $runspace gum style --border "rounded" --width $width "$title`n$header" --border-foreground $($Theme["purple"]) $c = $choices | gum filter --no-limit --height $height --indicator "👉 " --placeholder "Search in the list" --prompt.foreground $($Theme["yellow"]) --prompt "🔎 " $choices2 = @() ($choices -split '\n') | ForEach-Object { $temp = $_ -replace [char]27,"@" if ($temp -match '@[\[][\d1,3;]*m') { $temp = $temp -replace '@[\[][\d1,3;]*m', "" } $choices2 += $temp } $packages = @() if ($c) { $c | ForEach-Object { $index = $choices2.IndexOf($_) $packages += $InstalledPackages[$index] #| Select-Object -Property * -ExcludeProperty Available } } Clear-Host # } if ($session) { Close-Spinner -session $Session -runspace $runspace } if($uninstall) { uninstallPackages -packages $packages } if($update) { updatePackages -packages $packages } return $packages | Select-Object -Property * -ExcludeProperty Available } function installPackages { param( [package[]]$packages ) $packages | ForEach-Object { $Session, $runspace = Open-Spinner -label "Installing $($_.Name)" -type "Dots" $command = "winget install --id $($_.Id)" Invoke-Expression $command | Out-Null Close-Spinner -session $Session -runspace $runspace } } function uninstallPackages { param( [package[]]$packages ) $packages | ForEach-Object { $Session, $runspace = Open-Spinner -label "Uninstalling $($_.Name)" -type "Dots" $command = "winget uninstall --id $($_.Id)" Invoke-Expression $command | Out-Null Close-Spinner -session $Session -runspace $runspace } } function updatePackages { param( [package[]]$packages ) $packages | ForEach-Object { $Session, $runspace = Open-Spinner -label "Unpdating $($_.Name)" -type "Dots" $command = "winget upgrade --id $($_.Id)" Invoke-Expression $command | Out-Null Close-Spinner -session $Session -runspace $runspace } } function Find-WGPackage { param( [string]$query = $null, [string]$source = $null, [switch]$install = $false ) $SearchParams = @{} $Y = $host.ui.rawui.CursorPosition.Y $buffer = gum style "Enter search query" --border "rounded" --width ($Host.UI.RawUI.BufferSize.Width - 2) --border-foreground $($Theme["purple"]) $buffer | ForEach-Object { [System.Console]::write($_) } if (-not $query) { $query = gum input --placeholder "Search for a package" $SearchParams.Add("query", $query) } if ($source) { $SearchParams.Add("source", $source) } else { $source = gum style "every sources" --foreground "#FF0000" } if ($query) { $title = gum style $query --foreground "#00FF00" --bold $Session, $runspace = Open-Spinner -label "Searching for $title in $source" -type "Dots" $queries = $query.Split(",") $packages = @() $queries | ForEach-Object { $SearchParams["query"] = [string]$_.Trim() $packs = Find-WinGetPackage @SearchParams $packs | ForEach-Object { $packages += $_ } } [System.Console]::setcursorposition(0, $Y) } else { [System.Console]::setcursorposition(0, $Y) $buffer = gum style "No query specified" --border "rounded" --width ($Host.UI.RawUI.BufferSize.Width - 2) --foreground "#FF0000" $buffer | ForEach-Object { [System.Console]::write($_) } return $null } if ($packages) { # Clear-Host [column[]]$cols = @() $cols += [column]::new("Name", "Name", 40) $cols += [column]::new("Id", "Id", 40) $cols += [column]::new("Available", "Version", 20) [package[]]$InstalledPackages = @() $packages | ForEach-Object { $InstalledPackages += [package]::new($_.Name, $_.Id, $_.AvailableVersions, $_.Source, $_.IsUpdateAvailable, $_.InstalledVersion) } $choices = makeLines -columns $cols -items $InstalledPackages Close-Spinner -session $Session -runspace $runspace $width = $Host.UI.RawUI.BufferSize.Width - 2 $height = $Host.UI.RawUI.BufferSize.Height - 6 [System.Console]::setcursorposition(0, $Y) $title = makeTitle -title "Choose Packages to Install" -width $width $header = makeHeader -columns $cols gum style --border "rounded" --width $width "$title`n$header" --border-foreground $($Theme["purple"]) # $c = $choices | gum choose --selected-prefix "✔️" --no-limit --cursor "👉 " --height $height $c = $choices | gum filter --no-limit --height $height --indicator "👉 " --placeholder "Search in the list" --prompt.foreground $($Theme["yellow"]) --prompt "🔎 " [package[]]$packages = @() if ($c) { $c | ForEach-Object { $index = ($choices -split '\n').IndexOf($_) $packages += $InstalledPackages[$index] } } Clear-Host } else { Close-Spinner -session $Session -runspace $runspace } if ($install) { installPackages -packages $packages } return $packages | Select-Object -Property * -ExcludeProperty Available } |