From 2f71da06735d7cf06e62c524390da73e31e21db4 Mon Sep 17 00:00:00 2001 From: EnumDev Date: Mon, 22 Dec 2025 21:18:06 +0200 Subject: [PATCH] Rework package counting --- src/pms.go | 158 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 141 insertions(+), 17 deletions(-) diff --git a/src/pms.go b/src/pms.go index 2c6b8e3..4ba4189 100644 --- a/src/pms.go +++ b/src/pms.go @@ -2,25 +2,29 @@ package main import ( "fmt" + "os" "os/exec" + "path" + "strconv" "strings" ) type PackageManager struct { - Name string - ExecutableName string - PackageListCommand string + Name string + ExecutableName string + GetPackages func(...any) int + FunctionInput []any } var PackageManagers = []PackageManager{ - {Name: "dpkg", ExecutableName: "dpkg", PackageListCommand: "dpkg-query -f '${Package}\\n' -W"}, - {Name: "pacman", ExecutableName: "pacman", PackageListCommand: "pacman -Q"}, - {Name: "rpm", ExecutableName: "rpm", PackageListCommand: "rpm -qa"}, - {Name: "xbps", ExecutableName: "xbps-query", PackageListCommand: "xbps-query -l"}, - {Name: "bpm", ExecutableName: "bpm", PackageListCommand: "ls /var/lib/bpm/installed/"}, - {Name: "portage", ExecutableName: "emerge", PackageListCommand: "find /var/db/pkg/*/ -mindepth 1 -maxdepth 1"}, - {Name: "flatpak", ExecutableName: "flatpak", PackageListCommand: "flatpak list"}, - {Name: "snap", ExecutableName: "snap", PackageListCommand: "snap list | tail +2"}, + {Name: "dpkg", ExecutableName: "dpkg", GetPackages: pmFileLines, FunctionInput: []any{"/var/lib/dpkg/status", "Status: install ok installed"}}, + {Name: "pacman", ExecutableName: "pacman", GetPackages: pmDirectoryElements, FunctionInput: []any{"/var/lib/pacman/local/", true}}, + {Name: "rpm", ExecutableName: "rpm", GetPackages: pmShellCommandLines, FunctionInput: []any{"rpm -qa"}}, + {Name: "xbps", ExecutableName: "xbps-query", GetPackages: pmFileLines, FunctionInput: []any{"/var/db/xbps/pkgdb-0.38.plist", "installed"}}, + {Name: "bpm", ExecutableName: "bpm", GetPackages: pmDirectoryElements, FunctionInput: []any{"/var/lib/bpm/installed/"}}, + {Name: "portage", ExecutableName: "emerge", GetPackages: pmPortage}, + {Name: "flatpak", ExecutableName: "flatpak", GetPackages: pmFlatpak}, + {Name: "snap", ExecutableName: "snap", GetPackages: pmSnap}, } func (pm *PackageManager) CountPackages() int { @@ -29,12 +33,7 @@ func (pm *PackageManager) CountPackages() int { return 0 } - output, err := exec.Command("/bin/sh", "-c", pm.PackageListCommand).Output() - if err != nil { - return 0 - } - - return strings.Count(string(output), "\n") + return pm.GetPackages(pm.FunctionInput...) } func GetInstalledPackages() (ret string) { @@ -51,3 +50,128 @@ func GetInstalledPackages() (ret string) { return ret } + +func pmDirectoryElements(args ...any) int { + directory := args[0].(string) + dirsOnly := false + if len(args) >= 2 { + dirsOnly = args[1].(bool) + } + total := 0 + + dirEntries, _ := os.ReadDir(directory) + for _, entry := range dirEntries { + if !entry.IsDir() && dirsOnly { + continue + } + total++ + } + + return total +} + +func pmFileLines(args ...any) int { + filepath := args[0].(string) + mustContain := "" + if len(args) >= 2 { + mustContain = args[1].(string) + } + total := 0 + + content, err := os.ReadFile(filepath) + if err == nil { + for _, line := range strings.Split(strings.TrimSpace(string(content)), "\n") { + if mustContain != "" && !strings.Contains(line, mustContain) { + continue + } + + total++ + } + } + + return total +} + +func pmShellCommandLines(args ...any) int { + command := args[0].(string) + + output := runCommand(command, "/bin/sh") + + return len(strings.Split(output, "\n")) +} + +func pmShellCommandOutput(args ...any) int { + command := args[0].(string) + + output := runCommand(command, "/bin/sh") + + packageCount, _ := strconv.Atoi(output) + return packageCount +} + +func pmPortage(args ...any) int { + portageDir := "/var/db/pkg" + total := 0 + + dirEntries, _ := os.ReadDir(portageDir) + for _, repo := range dirEntries { + if !repo.IsDir() { + continue + } + + packages, _ := os.ReadDir(path.Join(portageDir, repo.Name())) + total += len(packages) + } + + return total +} + +func pmFlatpak(args ...any) int { + arch := GetArch() + flatpakDir := "/var/lib/flatpak" + total := 0 + + // Count applications + apps, err := os.ReadDir(path.Join(flatpakDir, "app")) + if err == nil { + for _, app := range apps { + if strings.HasSuffix(app.Name(), ".Locale") || strings.HasSuffix(app.Name(), ".Debug") { + continue + } + + dirEntries, _ := os.ReadDir(path.Join(flatpakDir, "app", app.Name(), arch)) + + total += len(dirEntries) + } + } + + // Count runtimes + runtimes, err := os.ReadDir(path.Join(flatpakDir, "runtime")) + if err == nil { + for _, runtime := range runtimes { + if strings.HasSuffix(runtime.Name(), ".Locale") || strings.HasSuffix(runtime.Name(), ".Debug") { + continue + } + + dirEntries, _ := os.ReadDir(path.Join(flatpakDir, "runtime", runtime.Name(), arch)) + + total += len(dirEntries) + } + } + + return total +} + +func pmSnap(args ...any) int { + total := pmDirectoryElements("/snap", true) + if total > 0 { + return total - 1 + } + + total = pmDirectoryElements("/var/lib/snapd/snap", true) + if total > 0 { + return total - 1 + } + + return 0 +}