Improve conflict checking

This commit is contained in:
2025-12-17 12:07:44 +02:00
parent aa229af8df
commit 04a71b573b
2 changed files with 91 additions and 41 deletions
+17 -5
View File
@@ -145,12 +145,9 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
operation.ReplaceObsoletePackages() operation.ReplaceObsoletePackages()
// Check for conflicts // Check for conflicts
conflicts, err := operation.CheckForConflicts() conflicts := operation.CheckForConflicts()
if err != nil {
return nil, fmt.Errorf("could not complete package conflict check: %s", err)
}
if len(conflicts) > 0 { if len(conflicts) > 0 {
err = nil err = fmt.Errorf("conflicts detected")
for pkg, conflict := range conflicts { for pkg, conflict := range conflicts {
err = errors.Join(err, PackageConflictErr{pkg, conflict}) err = errors.Join(err, PackageConflictErr{pkg, conflict})
} }
@@ -441,6 +438,21 @@ func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependenci
// Replace obsolete packages // Replace obsolete packages
operation.ReplaceObsoletePackages() operation.ReplaceObsoletePackages()
// Check for conflicts
conflicts := operation.CheckForConflicts()
if len(conflicts) > 0 {
err = fmt.Errorf("conflicts detected")
for pkg, conflict := range conflicts {
err = errors.Join(err, PackageConflictErr{pkg, conflict})
}
if !forceInstallation {
return nil, err
} else {
log.Printf("Warning: %s", err)
}
}
return operation, nil return operation, nil
} }
+74 -36
View File
@@ -277,54 +277,92 @@ func (operation *BPMOperation) ReplaceObsoletePackages() {
} }
} }
func (operation *BPMOperation) CheckForConflicts() (map[string][]string, error) { func (operation *BPMOperation) CheckForConflicts() map[string][]string {
conflicts := make(map[string][]string) conflicts := make(map[string][]string)
installedPackages, err := GetInstalledPackages(operation.RootDir)
if err != nil { // Get installed packages
return nil, err installedPackages := localPackageInformation[operation.RootDir]
}
allPackages := make([]*PackageInfo, len(installedPackages)) // Get packages to be removed
for i, value := range installedPackages { removedPackages := make([]string, 0)
bpmpkg := GetPackage(value, operation.RootDir) for _, value := range slices.Clone(operation.Actions) {
if bpmpkg == nil { if value.GetActionType() != "remove" {
return nil, fmt.Errorf("could not find installed package (%s)", value) continue
} }
allPackages[i] = bpmpkg.PkgInfo
removedPackages = append(removedPackages, value.(*RemovePackageAction).BpmPackage.PkgInfo.Name)
} }
// Add all new packages to the allPackages slice // Check for conflicts
for _, value := range slices.Clone(operation.Actions) { for _, value := range slices.Clone(operation.Actions) {
var pkgInfo *PackageInfo
if value.GetActionType() == "install" { if value.GetActionType() == "install" {
action := value.(*InstallPackageAction) pkgInfo = value.(*InstallPackageAction).BpmPackage.PkgInfo
pkgInfo := action.BpmPackage.PkgInfo
allPackages = append(allPackages, pkgInfo)
} else if value.GetActionType() == "fetch" { } else if value.GetActionType() == "fetch" {
action := value.(*FetchPackageAction) pkgInfo = value.(*FetchPackageAction).DatabaseEntry.Info
pkgInfo := action.DatabaseEntry.Info } else {
allPackages = append(allPackages, pkgInfo) continue
} else if value.GetActionType() == "remove" { }
action := value.(*RemovePackageAction)
pkgInfo := action.BpmPackage.PkgInfo // Check for conflicts with installed packages
for i := len(allPackages) - 1; i >= 0; i-- { for _, installedPkg := range installedPackages {
info := allPackages[i] // Skip if package is to be removed
if info.Name == pkgInfo.Name { if slices.Contains(removedPackages, installedPkg.PkgInfo.Name) {
allPackages = append(allPackages[:i], allPackages[i+1:]...) continue
}
// Skip if same package
if pkgInfo.Name == installedPkg.PkgInfo.Name {
continue
}
// Check for new package conflicts
if slices.Contains(pkgInfo.Conflicts, installedPkg.PkgInfo.Name) {
conflicts[pkgInfo.Name] = append(conflicts[pkgInfo.Name], installedPkg.PkgInfo.Name)
}
for _, vpkg := range installedPkg.PkgInfo.Provides {
if slices.Contains(pkgInfo.Conflicts, vpkg) {
conflicts[pkgInfo.Name] = append(conflicts[pkgInfo.Name], vpkg+" ("+installedPkg.PkgInfo.Name+")")
}
}
// Check for installed package conflicts
for _, vpkg := range pkgInfo.Provides {
if slices.Contains(installedPkg.PkgInfo.Conflicts, vpkg) {
conflicts[installedPkg.PkgInfo.Name] = append(conflicts[installedPkg.PkgInfo.Name], vpkg+" ("+pkgInfo.Name+")")
}
}
}
// Check for conflicts with other new packages
for _, value := range slices.Clone(operation.Actions) {
var pkgInfo2 *PackageInfo
if value.GetActionType() == "install" {
pkgInfo2 = value.(*InstallPackageAction).BpmPackage.PkgInfo
} else if value.GetActionType() == "fetch" {
pkgInfo2 = value.(*FetchPackageAction).DatabaseEntry.Info
} else {
continue
}
// Skip if same package
if pkgInfo.Name == pkgInfo2.Name {
continue
}
// Check for other package conflicts
if slices.Contains(pkgInfo.Conflicts, pkgInfo2.Name) {
conflicts[pkgInfo.Name] = append(conflicts[pkgInfo.Name], pkgInfo2.Name)
}
for _, vpkg := range pkgInfo2.Provides {
if slices.Contains(pkgInfo.Conflicts, vpkg) {
conflicts[pkgInfo.Name] = append(conflicts[pkgInfo.Name], vpkg+" ("+pkgInfo2.Name+")")
} }
} }
} }
} }
for _, value := range allPackages { return conflicts
for _, conflict := range value.Conflicts {
if slices.ContainsFunc(allPackages, func(info *PackageInfo) bool {
return info.Name == conflict
}) {
conflicts[value.Name] = append(conflicts[value.Name], conflict)
}
}
}
return conflicts, nil
} }
func (operation *BPMOperation) ShowOperationSummary() { func (operation *BPMOperation) ShowOperationSummary() {