Use BFS for finding unused dependencies

This commit is contained in:
2026-02-05 14:22:16 +02:00
parent 48cec35f0c
commit 8579c688d7
+47 -14
View File
@@ -220,34 +220,67 @@ func (operation *BPMOperation) Cleanup(cleanupMakeDepends bool) error {
} }
} }
// Get manually installed packages, resolve all their dependencies and add them to the keepPackages slice // Run BFS on all manually installed packages
keepPackages := make([]string, 0) visited := make([]string, 0)
for _, pkg := range slices.Clone(installedPackages) { for _, pkg := range installedPackages {
if getPackageLocalInfo(pkg.Name, operation.RootDir).GetInstallationReason() != InstallationReasonManual { if getPackageLocalInfo(pkg.Name, operation.RootDir).GetInstallationReason() != InstallationReasonManual {
continue continue
} }
// Do not resolve dependencies or add package to keepPackages slice if package removal action exists for it queue := make([]*PackageInfo, 0)
if _, ok := removeActions[pkg.Name]; ok {
continue
}
keepPackages = append(keepPackages, pkg.Name) queue = append(queue, pkg)
resolved := pkg.GetDependenciesRecursive(true, !cleanupMakeDepends, !cleanupMakeDepends, operation.RootDir)
for _, value := range resolved { for len(queue) > 0 {
if !slices.Contains(keepPackages, value) && !slices.Contains(MainBPMConfig.IgnorePackages, value) { v := queue[len(queue)-1]
keepPackages = append(keepPackages, value) queue = queue[:len(queue)-1]
// Skip package if it's to be removed
if _, ok := removeActions[v.Name]; ok {
continue
}
// Mark package as visited
visited = append(visited, v.Name)
// Get all package dependencies
depends := v.Depends
depends = append(depends, v.RuntimeDepends...)
if cleanupMakeDepends {
depends = append(depends, v.MakeDepends...)
depends = append(depends, v.CheckDepends...)
}
// Loop through all dependencies
for _, depend := range depends {
// Resolve dependency
var dependPkgInfo *PackageInfo
if providers := GetVirtualPackageInfo(depend, operation.RootDir); len(providers) > 0 {
dependPkgInfo = providers[0]
} else {
dependPkgInfo = GetPackageInfo(depend, operation.RootDir)
}
if dependPkgInfo == nil {
continue
}
// Mark dependency as visited and add it to the queue
if !slices.Contains(visited, dependPkgInfo.Name) {
visited = append(visited, dependPkgInfo.Name)
queue = append(queue, dependPkgInfo)
}
} }
} }
} }
// Get all installed packages that are not in the keepPackages slice and add them to the BPM operation // Remove all packages that were not discovered after running BFS
for _, pkg := range installedPackageNames { for _, pkg := range installedPackageNames {
// Do not add package removal action if there already is one // Do not add package removal action if there already is one
if _, ok := removeActions[pkg]; ok { if _, ok := removeActions[pkg]; ok {
continue continue
} }
if !slices.Contains(keepPackages, pkg) {
if !slices.Contains(visited, pkg) {
bpmpkg := GetPackage(pkg, operation.RootDir) bpmpkg := GetPackage(pkg, operation.RootDir)
if bpmpkg == nil { if bpmpkg == nil {
return errors.New("Error: could not find installed package (" + pkg + ")") return errors.New("Error: could not find installed package (" + pkg + ")")