diff --git a/src/bpm/main.go b/src/bpm/main.go index 9ef78cf..976d022 100644 --- a/src/bpm/main.go +++ b/src/bpm/main.go @@ -243,15 +243,11 @@ func showPackageInfo() { // Split package name and required version pkgName, _, _ := bpmlib.SplitPkgNameAndVersion(pkg) - entry, _, err := bpmlib.GetDatabaseEntry(pkgName) - if err != nil { - if providers := bpmlib.GetDatabaseVirtualPackageEntry(pkgName); len(providers) > 0 { - entry = providers[0] - } else { - log.Printf("Error: could not find package (%s) in any database\n", pkg) - exitCode = 1 - return - } + entry := bpmlib.ResolveDatabaseEntry(pkgName, rootDir) + if entry == nil { + log.Printf("Error: could not find package (%s) in any database\n", pkg) + exitCode = 1 + return } if !bpmlib.EvaluateDependency(pkg, entry.Info.Version) { diff --git a/src/bpmlib/databases.go b/src/bpmlib/databases.go index 58853c8..04d105e 100644 --- a/src/bpmlib/databases.go +++ b/src/bpmlib/databases.go @@ -207,35 +207,72 @@ func ReadLocalDatabaseFiles() (err error) { return nil } -func GetDatabaseEntry(str string) (*BPMDatabaseEntry, *BPMDatabase, error) { - split := strings.Split(str, "/") +func ResolveDatabaseEntry(pkg string, rootDir string) *BPMDatabaseEntry { + entry := GetDatabaseEntry(pkg) + if entry != nil { + return entry + } + + installedProviders := GetVirtualPackageInfo(pkg, rootDir) + if len(installedProviders) > 0 { + entry := GetDatabaseEntry(installedProviders[0].Name) + if entry != nil { + return entry + } + } + + databaseProviders := GetDatabaseVirtualPackageEntry(pkg) + if len(databaseProviders) > 0 { + entry := GetDatabaseEntry(databaseProviders[0].Info.Name) + if entry != nil { + return entry + } + } + + return nil +} + +func GetDatabaseEntry(pkg string) *BPMDatabaseEntry { + split := strings.Split(pkg, "/") if len(split) == 1 { pkgName := strings.TrimSpace(split[0]) if pkgName == "" { - return nil, nil, errors.New("could not find database entry for this package") + return nil } for _, db := range BPMDatabases { if db.ContainsPackage(pkgName) { - return db.Entries[pkgName], db, nil + return db.Entries[pkgName] } } - return nil, nil, errors.New("could not find database entry for this package") + return nil } else if len(split) == 2 { dbName := strings.TrimSpace(split[0]) pkgName := strings.TrimSpace(split[1]) if dbName == "" || pkgName == "" { - return nil, nil, errors.New("could not find database entry for this package") + return nil } db := BPMDatabases[dbName] if db == nil || !db.ContainsPackage(pkgName) { - return nil, nil, errors.New("could not find database entry for this package") + return nil } - return db.Entries[pkgName], db, nil + return db.Entries[pkgName] } else { - return nil, nil, errors.New("could not find database entry for this package") + return nil } } +func GetDatabaseVirtualPackageEntry(vpkg string) (providers []*BPMDatabaseEntry) { + for _, db := range BPMDatabases { + providers = append(providers, db.VirtualPackages[vpkg]...) + } + + slices.SortFunc(providers, func(a, b *BPMDatabaseEntry) int { + return strings.Compare(a.Info.Name, b.Info.Name) + }) + + return providers +} + func FindReplacement(pkg string) *BPMDatabaseEntry { for _, db := range BPMDatabases { for _, entry := range db.Entries { @@ -250,18 +287,6 @@ func FindReplacement(pkg string) *BPMDatabaseEntry { return nil } -func GetDatabaseVirtualPackageEntry(vpkg string) (providers []*BPMDatabaseEntry) { - for _, db := range BPMDatabases { - providers = append(providers, db.VirtualPackages[vpkg]...) - } - - slices.SortFunc(providers, func(a, b *BPMDatabaseEntry) int { - return strings.Compare(a.Info.Name, b.Info.Name) - }) - - return providers -} - func (db *BPMDatabase) FetchPackage(pkg string) (string, error) { // Check if package exists in database if !db.ContainsPackage(pkg) { diff --git a/src/bpmlib/dependencies.go b/src/bpmlib/dependencies.go index 61fa911..2e6ac7d 100644 --- a/src/bpmlib/dependencies.go +++ b/src/bpmlib/dependencies.go @@ -137,16 +137,13 @@ func ResolveDependencies(pkgInfo *PackageInfo, resolvedVirtualPackages map[strin continue } - // Find database entry for dependency - var dependEntry *BPMDatabaseEntry - if resolvedVpkg, ok := resolvedVirtualPackages[dependName]; ok { - dependEntry, _, _ = GetDatabaseEntry(resolvedVpkg) - } else if entry, _, _ := GetDatabaseEntry(dependName); entry != nil { - dependEntry = entry - } else if providers := GetDatabaseVirtualPackageEntry(dependName); len(providers) > 0 { - dependEntry = providers[0] + // Check resolved virtual packages + if resolvedPkg, ok := resolvedVirtualPackages[dependName]; ok { + dependName = resolvedPkg } + // Find database entry for dependency + dependEntry := ResolveDatabaseEntry(dependName, rootDir) if dependEntry == nil { unresolved = append(unresolved, depend) continue @@ -163,6 +160,14 @@ func ResolveDependencies(pkgInfo *PackageInfo, resolvedVirtualPackages map[strin continue } + // Resolve virtual resolved packages + for _, vpkg := range dependEntry.Info.Provides { + if _, ok := resolvedVirtualPackages[vpkg]; !ok { + resolvedVirtualPackages[vpkg] = dependEntry.Info.Name + } + } + + // Resolve entry dependencies if !slices.Contains(visited, dependEntry.Info.Name) { dfs(dependEntry.Info) resolved = append(resolved, ResolvedPackage{DatabaseEntry: dependEntry, InstallationReason: installationReason}) diff --git a/src/bpmlib/general.go b/src/bpmlib/general.go index 8a3d158..9852042 100644 --- a/src/bpmlib/general.go +++ b/src/bpmlib/general.go @@ -84,19 +84,8 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason, // Split package name and required version pkgName, _, _ := SplitPkgNameAndVersion(pkg) - var entry *BPMDatabaseEntry - - if e, _, err := GetDatabaseEntry(pkgName); err == nil { - entry = e - } else if providers := GetVirtualPackageInfo(pkgName, rootDir); len(providers) > 0 { - entry, _, err = GetDatabaseEntry(providers[0].Name) - if err != nil { - pkgsNotFound = append(pkgsNotFound, pkg) - continue - } - } else if providers := GetDatabaseVirtualPackageEntry(pkgName); len(providers) > 0 { - entry = providers[0] - } else { + entry := ResolveDatabaseEntry(pkgName, rootDir) + if entry == nil { pkgsNotFound = append(pkgsNotFound, pkg) continue } @@ -411,7 +400,7 @@ func UpdatePackages(rootDir string, syncDatabase, allowDowngrades, forceInstalla // Check if installed package can be replaced and install that instead if e := FindReplacement(pkg); e != nil { entry = e - } else if entry, _, err = GetDatabaseEntry(pkg); err != nil { + } else if entry = ResolveDatabaseEntry(pkg, rootDir); entry == nil { continue } @@ -440,15 +429,10 @@ func UpdatePackages(rootDir string, syncDatabase, allowDowngrades, forceInstalla } // Find database entry for missing dependency - dependEntry, _, err := GetDatabaseEntry(dependName) - if err != nil { - providers := GetDatabaseVirtualPackageEntry(dependName) - if len(providers) == 0 { - pkgsNotFound = append(pkgsNotFound, depend) - continue - } - - dependEntry = providers[0] + dependEntry := ResolveDatabaseEntry(dependName, rootDir) + if dependEntry == nil { + pkgsNotFound = append(pkgsNotFound, depend) + continue } // Skip dependency if action already exists @@ -487,15 +471,10 @@ func UpdatePackages(rootDir string, syncDatabase, allowDowngrades, forceInstalla } // Find database entry for missing dependency - dependEntry, _, err := GetDatabaseEntry(dependName) - if err != nil { - providers := GetDatabaseVirtualPackageEntry(dependName) - if len(providers) == 0 { - pkgsNotFound = append(pkgsNotFound, depend) - continue - } - - dependEntry = providers[0] + dependEntry := ResolveDatabaseEntry(dependName, rootDir) + if dependEntry == nil { + pkgsNotFound = append(pkgsNotFound, depend) + continue } // Skip dependency if ignored in config