//go:build linux package zypper import ( "git.jmbit.de/jmb/patchman/client/common" "git.jmbit.de/jmb/patchman/client/utils" "log" "os/exec" "strings" "sync" ) // GetInstalledList Because Zypper sadly can't give both the upgradeable and installed packages at the same time, // concurrently get both a list of all installed packages and all upgradeable and merge them func GetInstalledList() []common.ListPackage { var allPackages []common.ListPackage var upgradeablePackages []common.ListPackage var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done() allPackages = getAllPackagesList() log.Println("Got Zypper Package list") }() go func() { defer wg.Done() upgradeablePackages = getUpgradeableList() log.Println("Got Zypper upgradable Package list") }() wg.Wait() return utils.DedupAndMergePackageList(allPackages, upgradeablePackages) } func getAllPackagesList() []common.ListPackage { var packageList []common.ListPackage // List of all upgradeable packages cmd := exec.Command("/usr/bin/zypper", "se", "-si") out, err := cmd.Output() if err != nil { log.Printf("Could not get zypper packages %w", err) } // Convert Output into text and split it into newlines lines := strings.Split(string(out[:]), "\n") // Parse lines //TODO parallelize this for i, line := range lines { if i < 6 { continue } sections := strings.Split(line, "|") if len(sections) != 6 { log.Print(line) continue } name := strings.TrimSpace(sections[1]) source := strings.TrimSpace(sections[5]) version := strings.TrimSpace(sections[3]) architecture := strings.TrimSpace(sections[4]) listPackage := common.ListPackage{ Name: name, Source: source, Version: version, Architecture: architecture, PackageManager: "zypper", } packageList = append(packageList, listPackage) } return packageList } func getUpgradeableList() []common.ListPackage { var packageList []common.ListPackage // List of all upgradeable packages cmd := exec.Command("/usr/bin/zypper", "list-updates", "--all") out, err := cmd.Output() if err != nil { log.Printf("Could not get zypper packages %w", err) } // Convert Output into text and split it into newlines lines := strings.Split(string(out[:]), "\n") // Parse lines //TODO parallelize this for i, line := range lines { if i < 6 { continue } sections := strings.Split(line, "|") if len(sections) != 6 { log.Print(line) continue } name := strings.TrimSpace(sections[2]) source := strings.TrimSpace(sections[1]) version := strings.TrimSpace(sections[3]) upgradeableTo := strings.TrimSpace(sections[4]) architecture := strings.TrimSpace(sections[5]) listPackage := common.ListPackage{ Name: name, Source: source, Version: version, Architecture: architecture, Upgradeable: true, UpgradeableTo: upgradeableTo, PackageManager: "zypper", } packageList = append(packageList, listPackage) } return packageList }