package cmd import ( "fmt" "log" "runtime" "strings" "sync" "codeberg.org/Pata1704/system_setup_tool/internal/utils" pm "codeberg.org/Pata1704/system_setup_tool/pkg/packagemanager" "github.com/spf13/cobra" ) var searchCmd = &cobra.Command{ Use: "search [package_name]", Short: "Search for a package across package managers (will search in os|flatpak|homebrew)", Args: cobra.ExactArgs(1), Aliases: []string{"s"}, Run: func(cmd *cobra.Command, args []string) { packageName := args[0] managerName, _ := cmd.Flags().GetString("manager") switch managerName { case "os": managerName = "OS Package Manager" case "brew": managerName = "homebrew" } var managers []pm.PackageManager switch runtime.GOOS { case "linux": managers = []pm.PackageManager{ pm.NewOSManager(""), &pm.HomebrewManager{}, &pm.FlatpakManager{}, } case "windows": managers = []pm.PackageManager{ pm.NewOSManager(""), &pm.WingetManager{}, &pm.ChocoManager{}, } case "darwin": managers = []pm.PackageManager{ pm.NewOSManager(""), } default: log.Println("No Package Managers found") } if managerName != "" { for _, m := range managers { if strings.EqualFold(m.Name(), managerName) { searchAndDisplayResults(m, packageName) return } } fmt.Printf("Not supported for '%s'\n", managerName) return } searchConcurrently(managers, packageName) }, } func displayResults(results []string, manager string) { if len(results) == 0 { fmt.Printf("No results found in %s\n", manager) return } for _, result := range results { fmt.Printf("- %s\n", result) } } func searchAndDisplayResults(manager pm.PackageManager, packageName string) { fmt.Printf("Searching in %s:\n", manager.Name()) results := manager.SearchPackage(packageName) displayResults(results, manager.Name()) 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() if err := utils.LogToHistory("searched", packageName, result.manager.Name()); err != nil { fmt.Println("error logging action:", err) } } }