Unify normal and virtual package entry resolution

This commit is contained in:
2026-06-14 17:59:44 +03:00
parent 140cd3c64b
commit cb191dc16a
4 changed files with 75 additions and 70 deletions
+2 -6
View File
@@ -243,16 +243,12 @@ func showPackageInfo() {
// Split package name and required version // Split package name and required version
pkgName, _, _ := bpmlib.SplitPkgNameAndVersion(pkg) pkgName, _, _ := bpmlib.SplitPkgNameAndVersion(pkg)
entry, _, err := bpmlib.GetDatabaseEntry(pkgName) entry := bpmlib.ResolveDatabaseEntry(pkgName, rootDir)
if err != nil { if entry == 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) log.Printf("Error: could not find package (%s) in any database\n", pkg)
exitCode = 1 exitCode = 1
return return
} }
}
if !bpmlib.EvaluateDependency(pkg, entry.Info.Version) { if !bpmlib.EvaluateDependency(pkg, entry.Info.Version) {
log.Printf("Error: could not find package (%s) in any database\n", pkg) log.Printf("Error: could not find package (%s) in any database\n", pkg)
+46 -21
View File
@@ -207,35 +207,72 @@ func ReadLocalDatabaseFiles() (err error) {
return nil return nil
} }
func GetDatabaseEntry(str string) (*BPMDatabaseEntry, *BPMDatabase, error) { func ResolveDatabaseEntry(pkg string, rootDir string) *BPMDatabaseEntry {
split := strings.Split(str, "/") 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 { if len(split) == 1 {
pkgName := strings.TrimSpace(split[0]) pkgName := strings.TrimSpace(split[0])
if pkgName == "" { if pkgName == "" {
return nil, nil, errors.New("could not find database entry for this package") return nil
} }
for _, db := range BPMDatabases { for _, db := range BPMDatabases {
if db.ContainsPackage(pkgName) { 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 { } else if len(split) == 2 {
dbName := strings.TrimSpace(split[0]) dbName := strings.TrimSpace(split[0])
pkgName := strings.TrimSpace(split[1]) pkgName := strings.TrimSpace(split[1])
if dbName == "" || pkgName == "" { if dbName == "" || pkgName == "" {
return nil, nil, errors.New("could not find database entry for this package") return nil
} }
db := BPMDatabases[dbName] db := BPMDatabases[dbName]
if db == nil || !db.ContainsPackage(pkgName) { 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 { } 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 { func FindReplacement(pkg string) *BPMDatabaseEntry {
for _, db := range BPMDatabases { for _, db := range BPMDatabases {
for _, entry := range db.Entries { for _, entry := range db.Entries {
@@ -250,18 +287,6 @@ func FindReplacement(pkg string) *BPMDatabaseEntry {
return nil 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) { func (db *BPMDatabase) FetchPackage(pkg string) (string, error) {
// Check if package exists in database // Check if package exists in database
if !db.ContainsPackage(pkg) { if !db.ContainsPackage(pkg) {
+13 -8
View File
@@ -137,16 +137,13 @@ func ResolveDependencies(pkgInfo *PackageInfo, resolvedVirtualPackages map[strin
continue continue
} }
// Find database entry for dependency // Check resolved virtual packages
var dependEntry *BPMDatabaseEntry if resolvedPkg, ok := resolvedVirtualPackages[dependName]; ok {
if resolvedVpkg, ok := resolvedVirtualPackages[dependName]; ok { dependName = resolvedPkg
dependEntry, _, _ = GetDatabaseEntry(resolvedVpkg)
} else if entry, _, _ := GetDatabaseEntry(dependName); entry != nil {
dependEntry = entry
} else if providers := GetDatabaseVirtualPackageEntry(dependName); len(providers) > 0 {
dependEntry = providers[0]
} }
// Find database entry for dependency
dependEntry := ResolveDatabaseEntry(dependName, rootDir)
if dependEntry == nil { if dependEntry == nil {
unresolved = append(unresolved, depend) unresolved = append(unresolved, depend)
continue continue
@@ -163,6 +160,14 @@ func ResolveDependencies(pkgInfo *PackageInfo, resolvedVirtualPackages map[strin
continue 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) { if !slices.Contains(visited, dependEntry.Info.Name) {
dfs(dependEntry.Info) dfs(dependEntry.Info)
resolved = append(resolved, ResolvedPackage{DatabaseEntry: dependEntry, InstallationReason: installationReason}) resolved = append(resolved, ResolvedPackage{DatabaseEntry: dependEntry, InstallationReason: installationReason})
+7 -28
View File
@@ -84,19 +84,8 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
// Split package name and required version // Split package name and required version
pkgName, _, _ := SplitPkgNameAndVersion(pkg) pkgName, _, _ := SplitPkgNameAndVersion(pkg)
var entry *BPMDatabaseEntry entry := ResolveDatabaseEntry(pkgName, rootDir)
if entry == nil {
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 {
pkgsNotFound = append(pkgsNotFound, pkg) pkgsNotFound = append(pkgsNotFound, pkg)
continue continue
} }
@@ -411,7 +400,7 @@ func UpdatePackages(rootDir string, syncDatabase, allowDowngrades, forceInstalla
// Check if installed package can be replaced and install that instead // Check if installed package can be replaced and install that instead
if e := FindReplacement(pkg); e != nil { if e := FindReplacement(pkg); e != nil {
entry = e entry = e
} else if entry, _, err = GetDatabaseEntry(pkg); err != nil { } else if entry = ResolveDatabaseEntry(pkg, rootDir); entry == nil {
continue continue
} }
@@ -440,17 +429,12 @@ func UpdatePackages(rootDir string, syncDatabase, allowDowngrades, forceInstalla
} }
// Find database entry for missing dependency // Find database entry for missing dependency
dependEntry, _, err := GetDatabaseEntry(dependName) dependEntry := ResolveDatabaseEntry(dependName, rootDir)
if err != nil { if dependEntry == nil {
providers := GetDatabaseVirtualPackageEntry(dependName)
if len(providers) == 0 {
pkgsNotFound = append(pkgsNotFound, depend) pkgsNotFound = append(pkgsNotFound, depend)
continue continue
} }
dependEntry = providers[0]
}
// Skip dependency if action already exists // Skip dependency if action already exists
if ActionSliceIndex(operation.Actions, dependEntry.Info.Name) != -1 { if ActionSliceIndex(operation.Actions, dependEntry.Info.Name) != -1 {
continue continue
@@ -487,17 +471,12 @@ func UpdatePackages(rootDir string, syncDatabase, allowDowngrades, forceInstalla
} }
// Find database entry for missing dependency // Find database entry for missing dependency
dependEntry, _, err := GetDatabaseEntry(dependName) dependEntry := ResolveDatabaseEntry(dependName, rootDir)
if err != nil { if dependEntry == nil {
providers := GetDatabaseVirtualPackageEntry(dependName)
if len(providers) == 0 {
pkgsNotFound = append(pkgsNotFound, depend) pkgsNotFound = append(pkgsNotFound, depend)
continue continue
} }
dependEntry = providers[0]
}
// Skip dependency if ignored in config // Skip dependency if ignored in config
if rootDir == "/" && slices.Contains(MainBPMConfig.IgnorePackages, dependEntry.Info.Name) { if rootDir == "/" && slices.Contains(MainBPMConfig.IgnorePackages, dependEntry.Info.Name) {
continue continue