feat(cli): add concurrent execution of search and update to improve performance

This commit is contained in:
Patryk Hegenberg 2025-01-20 22:10:19 +01:00
parent 0306ad36ef
commit afaf7707aa
4 changed files with 85 additions and 22 deletions

View file

@ -2,7 +2,7 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [unreleased] ## [0.4.0] - 2025-01-20
### 🚀 Features ### 🚀 Features

View file

@ -5,6 +5,7 @@ import (
"log" "log"
"runtime" "runtime"
"strings" "strings"
"sync"
pm "system_setup_tool/packagemanager" pm "system_setup_tool/packagemanager"
@ -57,9 +58,7 @@ var searchCmd = &cobra.Command{
return return
} }
for _, manager := range managers { searchConcurrently(managers, packageName)
searchAndDisplayResults(manager, packageName)
}
}, },
} }
@ -79,3 +78,34 @@ func searchAndDisplayResults(manager pm.PackageManager, packageName string) {
displayResults(results, manager.Name()) displayResults(results, manager.Name())
fmt.Println() fmt.Println()
} }
func searchConcurrently(managers []pm.PackageManager, packageName string) {
var wg sync.WaitGroup
results := make(chan struct {
manager pm.PackageManager
results []string
}, len(managers))
for _, manager := range managers {
wg.Add(1)
go func(m pm.PackageManager) {
defer wg.Done()
searchResults := m.SearchPackage(packageName)
results <- struct {
manager pm.PackageManager
results []string
}{m, searchResults}
}(manager)
}
go func() {
wg.Wait()
close(results)
}()
for result := range results {
fmt.Printf("Results from %s:\n", result.manager.Name())
displayResults(result.results, result.manager.Name())
fmt.Println()
}
}

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"log" "log"
"runtime" "runtime"
"sync"
pm "system_setup_tool/packagemanager" pm "system_setup_tool/packagemanager"
"system_setup_tool/utils" "system_setup_tool/utils"
@ -64,20 +65,55 @@ var updateAllCmd = &cobra.Command{
Use: "update-all", Use: "update-all",
Short: "update all packages with all package managers.", Short: "update all packages with all package managers.",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
sudoPassword, err := utils.GetSudoPassword()
if err != nil {
log.Fatal(err)
}
managers := []pm.PackageManager{ var managers []pm.PackageManager
pm.NewOSManager(sudoPassword), switch runtime.GOOS {
&pm.HomebrewManager{}, case "linux":
&pm.FlatpakManager{}, sudoPassword, err := utils.GetSudoPassword()
&pm.PipxManager{}, if err != nil {
} log.Fatal(err)
for _, m := range managers { }
fmt.Printf("Updating %s-Packages\n", m.Name()) managers = []pm.PackageManager{
m.UpdateAllPackages() pm.NewOSManager(sudoPassword),
&pm.HomebrewManager{},
&pm.FlatpakManager{},
&pm.PipxManager{},
}
case "windows":
managers = []pm.PackageManager{
pm.NewOSManager(""),
&pm.WingetManager{},
&pm.ChocoManager{},
&pm.PipxManager{},
}
case "darwin":
sudoPassword, err := utils.GetSudoPassword()
if err != nil {
log.Fatal(err)
}
managers = []pm.PackageManager{
pm.NewOSManager(sudoPassword),
&pm.PipxManager{},
}
default:
log.Println("No Package Managers found")
} }
updateAllConcurrently(managers)
}, },
} }
func updateAllConcurrently(managers []pm.PackageManager) {
var wg sync.WaitGroup
for _, m := range managers {
wg.Add(1)
go func(manager pm.PackageManager) {
defer wg.Done()
fmt.Printf("Updating %s-Packages\n", manager.Name())
err := manager.UpdateAllPackages()
if err != nil {
log.Printf("Error updating %s: %v\n", manager.Name(), err)
}
}(m)
}
wg.Wait()
}

View file

@ -47,11 +47,8 @@ func (d *DnfManager) RemovePackage(pkg string) error {
} }
func (d *DnfManager) SearchPackage(pkg string) []string { func (d *DnfManager) SearchPackage(pkg string) []string {
cmd := "dnf search -y" cmd := shell.ExecCommand("dnf", "search", pkg)
fullCmd := fmt.Sprintf("%s %s", cmd, pkg) packages, err := cmd.Output()
command := shell.ExecCommand("sudo", "-S", "sh", "-c", fullCmd)
command.Stdin = strings.NewReader(d.SudoPassword + "\n")
packages, err := command.Output()
if err != nil { if err != nil {
log.Printf("error fetching %s packages: %v", d.Name(), err) log.Printf("error fetching %s packages: %v", d.Name(), err)
} }