From 3950c5f0d684037672072ee64194b63b833b8ed7 Mon Sep 17 00:00:00 2001 From: EnumDev Date: Tue, 12 May 2026 20:03:40 +0300 Subject: [PATCH] Dependency resolution improvements --- src/bpmlib/general.go | 16 +++--- src/bpmlib/operations.go | 115 +++++++++++++++++++-------------------- 2 files changed, 65 insertions(+), 66 deletions(-) diff --git a/src/bpmlib/general.go b/src/bpmlib/general.go index d0be1da..8a3d158 100644 --- a/src/bpmlib/general.go +++ b/src/bpmlib/general.go @@ -51,7 +51,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason, } } - operation.AppendAction(&InstallPackageAction{ + operation.Actions = append(operation.Actions, &InstallPackageAction{ File: pkg, InstallationReason: installationReason, BpmPackage: bpmpkg, @@ -75,7 +75,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason, } } - operation.AppendAction(&InstallPackageAction{ + operation.Actions = append(operation.Actions, &InstallPackageAction{ File: pkg, InstallationReason: installationReason, BpmPackage: bpmpkg, @@ -120,7 +120,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason, } } - operation.AppendAction(&FetchPackageAction{ + operation.Actions = append(operation.Actions, &FetchPackageAction{ InstallationReason: installationReason, DatabaseEntry: entry, }) @@ -206,7 +206,7 @@ func RemovePackages(rootDir string, force, cleanupDependencies bool, packages .. if bpmpkg == nil { continue } - operation.AppendAction(&RemovePackageAction{BpmPackage: bpmpkg}) + operation.Actions = append(operation.Actions, &RemovePackageAction{BpmPackage: bpmpkg}) } // Do package cleanup @@ -421,7 +421,7 @@ func UpdatePackages(rootDir string, syncDatabase, allowDowngrades, forceInstalla } else { comparison := CompareVersions(entry.Info.GetFullVersion(), installedInfo.GetFullVersion()) if (!allowDowngrades && comparison > 0) || (allowDowngrades && comparison != 0) { - operation.AppendAction(&FetchPackageAction{ + operation.Actions = append(operation.Actions, &FetchPackageAction{ InstallationReason: GetPackage(pkg, rootDir).LocalInfo.GetInstallationReason(), DatabaseEntry: entry, }) @@ -452,7 +452,7 @@ func UpdatePackages(rootDir string, syncDatabase, allowDowngrades, forceInstalla } // Skip dependency if action already exists - if operation.ActionsContainPackage(dependEntry.Info.Name) { + if ActionSliceIndex(operation.Actions, dependEntry.Info.Name) != -1 { continue } @@ -468,7 +468,7 @@ func UpdatePackages(rootDir string, syncDatabase, allowDowngrades, forceInstalla } // Fetch dependency - operation.AppendAction(&FetchPackageAction{ + operation.Actions = append(operation.Actions, &FetchPackageAction{ InstallationReason: InstallationReasonDependency, DatabaseEntry: dependEntry, }) @@ -510,7 +510,7 @@ func UpdatePackages(rootDir string, syncDatabase, allowDowngrades, forceInstalla } // Fetch dependency - operation.AppendAction(&FetchPackageAction{ + operation.Actions = append(operation.Actions, &FetchPackageAction{ InstallationReason: InstallationReasonDependency, DatabaseEntry: dependEntry, }) diff --git a/src/bpmlib/operations.go b/src/bpmlib/operations.go index b5fcc28..e0c6d3c 100644 --- a/src/bpmlib/operations.go +++ b/src/bpmlib/operations.go @@ -23,54 +23,6 @@ type BPMOperation struct { hasFetchedPackages bool } -func (operation *BPMOperation) ActionsContainPackage(pkg string) bool { - for _, action := range operation.Actions { - if action.GetActionType() == "install" { - if action.(*InstallPackageAction).BpmPackage.PkgInfo.Name == pkg { - return true - } - } else if action.GetActionType() == "fetch" { - if action.(*FetchPackageAction).DatabaseEntry.Info.Name == pkg { - return true - } - } else if action.GetActionType() == "remove" { - if action.(*RemovePackageAction).BpmPackage.PkgInfo.Name == pkg { - return true - } - } - } - return false -} - -func (operation *BPMOperation) AppendAction(action OperationAction) { - operation.InsertActionAt(len(operation.Actions), action) -} - -func (operation *BPMOperation) InsertActionAt(index int, action OperationAction) { - if len(operation.Actions) == index { // nil or empty slice or after last element - operation.Actions = append(operation.Actions, action) - } else { - operation.Actions = append(operation.Actions[:index+1], operation.Actions[index:]...) // index < len(a) - operation.Actions[index] = action - } -} - -func (operation *BPMOperation) RemoveAction(pkg, actionType string) { - operation.Actions = slices.DeleteFunc(operation.Actions, func(a OperationAction) bool { - if a.GetActionType() != actionType { - return false - } - if a.GetActionType() == "install" { - return a.(*InstallPackageAction).BpmPackage.PkgInfo.Name == pkg - } else if a.GetActionType() == "fetch" { - return a.(*FetchPackageAction).DatabaseEntry.Info.Name == pkg - } else if a.GetActionType() == "remove" { - return a.(*RemovePackageAction).BpmPackage.PkgInfo.Name == pkg - } - return false - }) -} - func (operation *BPMOperation) GetTotalDownloadSize() int64 { var ret int64 = 0 for _, action := range operation.Actions { @@ -136,8 +88,8 @@ func (operation *BPMOperation) ResolveDependencies(installRuntimeDepends bool) { } // Discover all dependencies - pos := 0 - for _, value := range slices.Clone(operation.Actions) { + newActions := make([]OperationAction, 0) + for _, value := range operation.Actions { var pkgInfo *PackageInfo if value.GetActionType() == "install" { action := value.(*InstallPackageAction) @@ -156,11 +108,12 @@ func (operation *BPMOperation) ResolveDependencies(installRuntimeDepends bool) { operation.UnresolvedDepends = removeDuplicates(operation.UnresolvedDepends) for _, resolvedPkg := range resolved { - if !operation.ActionsContainPackage(resolvedPkg.DatabaseEntry.Info.Name) && resolvedPkg.DatabaseEntry.Info.Name != pkgInfo.Name { - operation.InsertActionAt(pos, &FetchPackageAction{ + if ActionSliceIndex(newActions, resolvedPkg.DatabaseEntry.Info.Name) == -1 { // Dependency not in actions slice + var action OperationAction = &FetchPackageAction{ InstallationReason: resolvedPkg.InstallationReason, DatabaseEntry: resolvedPkg.DatabaseEntry, - }) + } + newActions = append(newActions, action) for _, vpkg := range resolvedPkg.DatabaseEntry.Info.Provides { if _, ok := resolvedVirtualPackages[vpkg]; !ok { @@ -168,12 +121,19 @@ func (operation *BPMOperation) ResolveDependencies(installRuntimeDepends bool) { } } - pos++ + // Check if can move original action + if i := ActionSliceIndex(operation.Actions, resolvedPkg.DatabaseEntry.Info.Name); i != -1 { + newActions[len(newActions)-1] = operation.Actions[i] + } } } - pos++ + if ActionSliceIndex(newActions, pkgInfo.Name) == -1 { + newActions = append(newActions, value) + } } + + operation.Actions = newActions } func (operation *BPMOperation) Cleanup(cleanupMakeDepends bool) error { @@ -289,10 +249,11 @@ func (operation *BPMOperation) ReplaceObsoletePackages() { } for _, r := range pkgInfo.Replaces { - if bpmpkg := GetPackage(r, operation.RootDir); bpmpkg != nil && !operation.ActionsContainPackage(bpmpkg.PkgInfo.Name) { - operation.InsertActionAt(0, &RemovePackageAction{ + if bpmpkg := GetPackage(r, operation.RootDir); bpmpkg != nil && ActionSliceIndex(operation.Actions, bpmpkg.PkgInfo.Name) == -1 { + var action OperationAction = &RemovePackageAction{ BpmPackage: bpmpkg, - }) + } + operation.Actions = slices.Insert(operation.Actions, 0, action) } } } @@ -832,3 +793,41 @@ type RemovePackageAction struct { func (action *RemovePackageAction) GetActionType() string { return "remove" } + +func ActionSliceIndex(actions []OperationAction, pkg string) int { + for i, action := range actions { + if action.GetActionType() == "install" { + if action.(*InstallPackageAction).BpmPackage.PkgInfo.Name == pkg { + return i + } + } else if action.GetActionType() == "fetch" { + if action.(*FetchPackageAction).DatabaseEntry.Info.Name == pkg { + return i + } + } else if action.GetActionType() == "remove" { + if action.(*RemovePackageAction).BpmPackage.PkgInfo.Name == pkg { + return i + } + } + } + + return -1 +} + +func ActionSliceRemove(actions []OperationAction, pkg, actionType string) []OperationAction { + actions = slices.DeleteFunc(actions, func(a OperationAction) bool { + if a.GetActionType() != actionType { + return false + } + if a.GetActionType() == "install" { + return a.(*InstallPackageAction).BpmPackage.PkgInfo.Name == pkg + } else if a.GetActionType() == "fetch" { + return a.(*FetchPackageAction).DatabaseEntry.Info.Name == pkg + } else if a.GetActionType() == "remove" { + return a.(*RemovePackageAction).BpmPackage.PkgInfo.Name == pkg + } + return false + }) + + return actions +}