From d56005e63e817857ee30b5b14d0405775f6db022 Mon Sep 17 00:00:00 2001 From: EnumDev Date: Sat, 18 Oct 2025 09:16:15 +0300 Subject: [PATCH] Improve database entry querying --- src/bpm/main.go | 18 +++++--- src/bpmlib/databases.go | 94 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 5 deletions(-) diff --git a/src/bpm/main.go b/src/bpm/main.go index 6ebf379..097469b 100644 --- a/src/bpm/main.go +++ b/src/bpm/main.go @@ -185,9 +185,6 @@ func showPackageInfo() { } for n, pkg := range packages { - var info *bpmlib.PackageInfo - isFile := false - showInstallationReason := false if showDatabaseInfo { var err error var entry *bpmlib.BPMDatabaseEntry @@ -199,8 +196,19 @@ func showPackageInfo() { return } } - info = entry.Info - } else if stat, err := os.Stat(pkg); err == nil && !stat.IsDir() { + + if n != 0 { + fmt.Println() + } + fmt.Println(entry.CreateReadableInfo(rootDir)) + + return + } + + var info *bpmlib.PackageInfo + isFile := false + showInstallationReason := false + if stat, err := os.Stat(pkg); err == nil && !stat.IsDir() { bpmpkg, err := bpmlib.ReadPackage(pkg) if err != nil { log.Printf("Error: could not read package: %s\n", err) diff --git a/src/bpmlib/databases.go b/src/bpmlib/databases.go index 22427cf..1d9405f 100644 --- a/src/bpmlib/databases.go +++ b/src/bpmlib/databases.go @@ -3,6 +3,7 @@ package bpmlib import ( "errors" "fmt" + "maps" "net/url" "os" "path" @@ -16,6 +17,7 @@ type BPMDatabase struct { DatabaseVersion int `yaml:"database_version"` Entries map[string]*BPMDatabaseEntry `yaml:"entries"` VirtualPackages map[string][]string + Name string Source string } @@ -54,6 +56,7 @@ func (db *configDatabase) ReadLocalDatabase() error { // Initialize struct values database.VirtualPackages = make(map[string][]string) + database.Name = db.Name database.Source = db.Source entriesToRemove := make([]string, 0) @@ -247,3 +250,94 @@ func (db *BPMDatabase) FetchPackage(pkg string) (string, error) { return path.Join("/var/cache/bpm/fetched/", path.Base(entry.Filepath)), nil } + +func (entry *BPMDatabaseEntry) GetEntryDependants() (dependants []string) { + dependantsMap := make(map[string][]string) + for _, db := range BPMDatabases { + for _, e := range db.Entries { + if slices.Contains(e.Info.Depends, entry.Info.Name) { + dependantsMap[e.Info.Name] = append(dependantsMap[e.Info.Name], e.Database.Name) + } + } + } + + // Get keys + keySlice := slices.Collect(maps.Keys(dependantsMap)) + slices.Sort(keySlice) + + // Add all dependant entries to slice in alphabetical order + for _, entryName := range keySlice { + dbs := dependantsMap[entryName] + if len(dbs) > 1 { + for _, db := range dbs { + dependants = append(dependants, db+"/"+entryName) + } + } else { + dependants = append(dependants, entryName) + } + } + + return dependants +} + +func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string) string { + ret := make([]string, 0) + appendArray := func(label string, array []string, sort bool) { + if len(array) == 0 { + return + } + + if sort { + // Sort array + slices.Sort(array) + } + + ret = append(ret, fmt.Sprintf("%s: %s", label, strings.Join(array, ", "))) + } + + ret = append(ret, "Name: "+entry.Info.Name) + ret = append(ret, "Database: "+entry.Database.Name) + ret = append(ret, "Description: "+entry.Info.Description) + ret = append(ret, "Version: "+entry.Info.GetFullVersion()) + ret = append(ret, "URL: "+entry.Info.Url) + ret = append(ret, "License: "+entry.Info.License) + ret = append(ret, "Architecture: "+entry.Info.Arch) + ret = append(ret, "Type: "+entry.Info.Type) + appendArray("Dependencies", entry.Info.Depends, true) + if entry.Info.Type == "source" { + appendArray("Make Dependencies", entry.Info.MakeDepends, true) + } + appendArray("Optional dependencies", entry.Info.OptionalDepends, true) + dependants := entry.GetEntryDependants() + if len(dependants) > 0 { + appendArray("Dependant packages", dependants, false) + } + appendArray("Conflicting packages", entry.Info.Conflicts, true) + appendArray("Provided packages", entry.Info.Provides, true) + appendArray("Replaces packages", entry.Info.Replaces, true) + + if entry.Info.Type == "source" && len(entry.Info.SplitPackages) != 0 { + splitPkgs := make([]string, len(entry.Info.SplitPackages)) + for i, splitPkgInfo := range entry.Info.SplitPackages { + splitPkgs[i] = splitPkgInfo.Name + } + appendArray("Split Packages", splitPkgs, true) + } + + if rootDir != "" && IsPackageInstalled(entry.Info.Name, rootDir) { + installationReason := GetInstallationReason(entry.Info.Name, rootDir) + var installationReasonString string + switch installationReason { + case InstallationReasonManual: + installationReasonString = "Manual" + case InstallationReasonDependency: + installationReasonString = "Dependency" + case InstallationReasonMakeDependency: + installationReasonString = "Make dependency" + default: + installationReasonString = "Unknown" + } + ret = append(ret, "Installation Reason: "+installationReasonString) + } + return strings.Join(ret, "\n") +}