//go:build linux package apt import ( "git.jmbit.de/jmb/patchman/client/common" "log" "os/exec" "regexp" "strings" ) func GetInstalledList() []common.ListPackage { var packageList []common.ListPackage cmd := exec.Command("/usr/bin/apt", "list", "--installed") cmd.Env = append(cmd.Environ(), "APT_FRONTEND=noninteractive") out, err := cmd.Output() if err != nil { log.Printf("Could not get apt packages %w", err) } // Convert Output into text and split it into newlines lines := strings.Split(string(out[:]), "\n") //TODO parallelize this // Parse lines for _, line := range lines { // arcane regex magic nameRegex := regexp.MustCompile(`^[a-z0-9\-]*`) suiteRegex := regexp.MustCompile(`(:?\/)[A-Za-z0-9]*(:?,)`) versionRegex := regexp.MustCompile(`(:?,now\s)[A-Za-z0-9\:\-\+\.]*(:?\s)`) architectureRegex := regexp.MustCompile(`(:?\s)[a-z0-9]*(:?\s\[)`) upgradeableToRegex := regexp.MustCompile(`(:?upgradable\sto\:\s)[a-z0-9\:\-\+\.]*(:?\])`) name := nameRegex.FindString(line) suite := suiteRegex.FindString(line) version := versionRegex.FindString(line) architecture := architectureRegex.FindString(line) upgradeable := upgradeableToRegex.MatchString(line) upgradeableTo := upgradeableToRegex.FindString(line) listPackage := common.ListPackage{ Name: name, Source: suite, Version: version, Architecture: architecture, Upgradeable: upgradeable, UpgradeableTo: upgradeableTo, PackageManager: "apt", } packageList = append(packageList, listPackage) } return packageList }