5 Commits
6 changed files with 121 additions and 280 deletions
+7 -19
View File
@@ -92,7 +92,6 @@ func main() {
currentFlagSet.BoolP("optional", "o", false, "Install all optional dependencies") currentFlagSet.BoolP("optional", "o", false, "Install all optional dependencies")
currentFlagSet.String("installation-reason", "", "Specify the installation reason to use for the specified packages") currentFlagSet.String("installation-reason", "", "Specify the installation reason to use for the specified packages")
currentFlagSet.BoolP("reinstall", "r", false, "Reinstall the specified packages") currentFlagSet.BoolP("reinstall", "r", false, "Reinstall the specified packages")
currentFlagSet.BoolP("reinstall-all", "a", false, "Reinstall the specified packages and their dependencies")
currentFlagSet.IntP("jobs", "j", bpmlib.CompilationBPMConfig.CompilationJobs, "Set the amount of concurrent processes to use for source package compilation") currentFlagSet.IntP("jobs", "j", bpmlib.CompilationBPMConfig.CompilationJobs, "Set the amount of concurrent processes to use for source package compilation")
currentFlagSet.BoolP("skip-checks", "s", false, "Skip the check function in source.sh scripts") currentFlagSet.BoolP("skip-checks", "s", false, "Skip the check function in source.sh scripts")
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Install the specified packages", os.Args[2:]) setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Install the specified packages", os.Args[2:])
@@ -545,8 +544,7 @@ func installPackages() {
installRuntime, _ := currentFlagSet.GetBool("runtime") installRuntime, _ := currentFlagSet.GetBool("runtime")
installOptional, _ := currentFlagSet.GetBool("optional") installOptional, _ := currentFlagSet.GetBool("optional")
installationReason, _ := currentFlagSet.GetString("installation-reason") installationReason, _ := currentFlagSet.GetString("installation-reason")
reinstall, _ := currentFlagSet.GetBool("reinstall") reinstallPackages, _ := currentFlagSet.GetBool("reinstall")
reinstallAll, _ := currentFlagSet.GetBool("reinstall-all")
skipChecks, _ := currentFlagSet.GetBool("skip-checks") skipChecks, _ := currentFlagSet.GetBool("skip-checks")
compilationJobs, _ := currentFlagSet.GetInt("jobs") compilationJobs, _ := currentFlagSet.GetInt("jobs")
@@ -580,16 +578,6 @@ func installPackages() {
return return
} }
// Get reinstall method
var reinstallMethod bpmlib.ReinstallMethod
if reinstallAll {
reinstallMethod = bpmlib.ReinstallMethodAll
} else if reinstall {
reinstallMethod = bpmlib.ReinstallMethodSpecified
} else {
reinstallMethod = bpmlib.ReinstallMethodNone
}
// Create BPM Lock file // Create BPM Lock file
fileLock, err := bpmlib.LockBPM(rootDir) fileLock, err := bpmlib.LockBPM(rootDir)
if err != nil { if err != nil {
@@ -616,7 +604,7 @@ func installPackages() {
} }
// Create installation operation // Create installation operation
operation, err := bpmlib.InstallPackages(rootDir, ir, reinstallMethod, installRuntime, installOptional, force, !skipChecks, verbose, packages...) operation, err := bpmlib.InstallPackages(rootDir, ir, reinstallPackages, installRuntime, installOptional, force, !skipChecks, verbose, packages...)
if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) { if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) {
log.Printf("Error: %s", err) log.Printf("Error: %s", err)
exitCode = 1 exitCode = 1
@@ -1285,12 +1273,12 @@ func compilePackage() {
return return
} }
// Get direct common and make dependencies // Get common, make and check dependencies
totalDepends := make([]string, 0) totalDepends := make([]string, 0)
for _, depend := range bpmpkg.PkgInfo.GetDependencies(true, !skipChecks, false, false) { totalDepends = append(totalDepends, bpmpkg.PkgInfo.Depends...)
if !slices.Contains(totalDepends, depend.PkgName) { totalDepends = append(totalDepends, bpmpkg.PkgInfo.MakeDepends...)
totalDepends = append(totalDepends, depend.PkgName) if !skipChecks {
} totalDepends = append(totalDepends, bpmpkg.PkgInfo.CheckDepends...)
} }
// Get unmet dependencies // Get unmet dependencies
+4
View File
@@ -236,6 +236,10 @@ func GetDatabaseVirtualPackageEntry(vpkg string) (providers []*BPMDatabaseEntry)
providers = append(providers, db.VirtualPackages[vpkg]...) 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 return providers
} }
+61 -224
View File
@@ -1,234 +1,10 @@
package bpmlib package bpmlib
import ( import (
"fmt"
"slices" "slices"
"strings" "strings"
) )
type pkgInstallationReason struct {
PkgName string
InstallationReason InstallationReason
}
func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeCheckDepends, includeRuntimeDepends, includeOptionalDepends bool) []pkgInstallationReason {
allDepends := make([]pkgInstallationReason, 0)
for _, depend := range pkgInfo.Depends {
if !slices.ContainsFunc(allDepends, func(p pkgInstallationReason) bool {
return p.PkgName == depend
}) {
allDepends = append(allDepends, pkgInstallationReason{
PkgName: depend,
InstallationReason: InstallationReasonDependency,
})
}
}
if includeOptionalDepends {
for _, depend := range pkgInfo.OptionalDepends {
depend = strings.SplitN(depend, ":", 2)[0]
if !slices.ContainsFunc(allDepends, func(p pkgInstallationReason) bool {
return p.PkgName == depend
}) {
allDepends = append(allDepends, pkgInstallationReason{
PkgName: depend,
InstallationReason: InstallationReasonManual,
})
}
}
}
if includeRuntimeDepends {
for _, depend := range pkgInfo.RuntimeDepends {
if !slices.ContainsFunc(allDepends, func(p pkgInstallationReason) bool {
return p.PkgName == depend
}) {
allDepends = append(allDepends, pkgInstallationReason{
PkgName: depend,
InstallationReason: InstallationReasonDependency,
})
}
}
}
if includeMakeDepends {
for _, depend := range pkgInfo.MakeDepends {
if !slices.ContainsFunc(allDepends, func(p pkgInstallationReason) bool {
return p.PkgName == depend
}) {
allDepends = append(allDepends, pkgInstallationReason{
PkgName: depend,
InstallationReason: InstallationReasonMakeDependency,
})
}
}
}
if includeCheckDepends {
for _, depend := range pkgInfo.CheckDepends {
if !slices.ContainsFunc(allDepends, func(p pkgInstallationReason) bool {
return p.PkgName == depend
}) {
allDepends = append(allDepends, pkgInstallationReason{
PkgName: depend,
InstallationReason: InstallationReasonMakeDependency,
})
}
}
}
// Skip ignored packages
allDepends = slices.DeleteFunc(allDepends, func(depend pkgInstallationReason) bool {
return slices.Contains(MainBPMConfig.IgnorePackages, depend.PkgName)
})
return allDepends
}
func (pkgInfo *PackageInfo) GetDependenciesRecursive(includeRuntimeDepends, includeCheckDepends, includeMakeDepends bool, rootDir string) (resolved []string) {
// Initialize slices
resolved = make([]string, 0)
unresolved := make([]string, 0)
// Call unexported function
pkgInfo.getDependenciesRecursive(&resolved, &unresolved, includeRuntimeDepends, includeMakeDepends, includeCheckDepends, rootDir)
return resolved
}
func (pkgInfo *PackageInfo) getDependenciesRecursive(resolved *[]string, unresolved *[]string, includeRuntimeDepends, includeMakeDepends, includeCheckDepends bool, rootDir string) {
// Add current package name to unresolved slice
*unresolved = append(*unresolved, pkgInfo.Name)
// Loop through all dependencies
for _, pkgIR := range pkgInfo.GetDependencies(includeMakeDepends, includeCheckDepends, includeRuntimeDepends, false) {
depend := pkgIR.PkgName
if providers := GetVirtualPackageInfo(depend, rootDir); len(providers) > 0 {
depend = providers[0].Name
}
if !slices.Contains(*resolved, depend) {
// Add current dependency to resolved slice when circular dependency is detected
if slices.Contains(*unresolved, depend) {
if !slices.Contains(*resolved, depend) {
*resolved = append(*resolved, depend)
}
continue
}
dependInfo := GetPackageInfo(depend, rootDir)
if dependInfo != nil {
dependInfo.getDependenciesRecursive(resolved, unresolved, includeRuntimeDepends, includeMakeDepends, includeCheckDepends, rootDir)
}
}
}
if !slices.Contains(*resolved, pkgInfo.Name) {
*resolved = append(*resolved, pkgInfo.Name)
}
*unresolved = stringSliceRemove(*unresolved, pkgInfo.Name)
}
func ResolveAllPackageDependenciesFromDatabases(pkgInfo *PackageInfo, resolvedVirtualPkgs map[string]string, checkMake, checkCheck, checkRuntime, checkOptional, ignoreInstalled, verbose bool, rootDir string) (resolved []pkgInstallationReason, unresolved []string) {
// Initialize slices and maps
resolved = make([]pkgInstallationReason, 0)
unresolved = make([]string, 0)
if resolvedVirtualPkgs == nil {
resolvedVirtualPkgs = make(map[string]string)
}
// Call unexported function
resolvePackageDependenciesFromDatabase(&resolved, &unresolved, resolvedVirtualPkgs, pkgInfo, checkMake, checkCheck, checkRuntime, checkOptional, ignoreInstalled, verbose, rootDir)
// Remove main package from unresolved slice
unresolved = stringSliceRemove(unresolved, pkgInfo.Name)
return resolved, unresolved
}
func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, unresolved *[]string, resolvedVirtualPkgs map[string]string, pkgInfo *PackageInfo, checkMake, checkCheck, checkRuntime, checkOptional, ignoreInstalled, verbose bool, rootDir string) {
// Add current package name to unresolved slice
*unresolved = append(*unresolved, pkgInfo.Name)
for _, vpkg := range pkgInfo.Provides {
if _, ok := resolvedVirtualPkgs[vpkg]; !ok {
resolvedVirtualPkgs[vpkg] = pkgInfo.Name
}
}
// Loop through all dependencies
for _, pkgIR := range pkgInfo.GetDependencies(pkgInfo.Type == "source", pkgInfo.Type == "source" && checkCheck, checkRuntime, checkOptional) {
// Skip dependency if it has already been resolved
if slices.ContainsFunc(*resolved, func(p pkgInstallationReason) bool {
return p.PkgName == pkgIR.PkgName
}) {
continue
}
// Add current dependency to resolved slice when circular dependency is detected
if slices.Contains(*unresolved, pkgIR.PkgName) {
if verbose {
fmt.Printf("Circular dependency was detected (%s -> %s). Installing %s first\n", pkgInfo.Name, pkgIR.PkgName, pkgIR.PkgName)
}
*resolved = append(*resolved, pkgInstallationReason{
PkgName: pkgIR.PkgName,
InstallationReason: pkgIR.InstallationReason,
})
continue
}
// Skip dependency if it is already installed or provided
if providers := GetVirtualPackageInfo(pkgIR.PkgName, rootDir); ignoreInstalled && len(providers) > 0 {
continue
}
// Get database entry for dependency
var err error
var entry *BPMDatabaseEntry
entry, _, err = GetDatabaseEntry(pkgIR.PkgName)
if err != nil {
if resolvedVirtualPkg, ok := resolvedVirtualPkgs[pkgIR.PkgName]; ok {
// Virtual package already resolved
// Move dependency from the unresolved slice to the resolved slice
if !slices.ContainsFunc(*resolved, func(p pkgInstallationReason) bool {
return p.PkgName == resolvedVirtualPkg
}) {
*resolved = append(*resolved, pkgInstallationReason{
PkgName: resolvedVirtualPkg,
InstallationReason: pkgIR.InstallationReason,
})
}
*unresolved = stringSliceRemove(*unresolved, resolvedVirtualPkg)
continue
} else if providers := GetDatabaseVirtualPackageEntry(pkgIR.PkgName); len(providers) > 0 {
// Virtual package found in database
entry = providers[0]
} else {
// Virtual package not found
if !slices.Contains(*unresolved, pkgIR.PkgName) {
*unresolved = append(*unresolved, pkgIR.PkgName)
}
continue
}
}
// Resolve the dependencies of this dependency
resolvePackageDependenciesFromDatabase(resolved, unresolved, resolvedVirtualPkgs, entry.Info, checkMake, checkCheck, checkRuntime, false, ignoreInstalled, verbose, rootDir)
// Move dependency from the unresolved slice to the resolved slice
if !slices.ContainsFunc(*resolved, func(p pkgInstallationReason) bool {
return p.PkgName == entry.Info.Name
}) {
*resolved = append(*resolved, pkgInstallationReason{
PkgName: entry.Info.Name,
InstallationReason: pkgIR.InstallationReason,
})
}
*unresolved = stringSliceRemove(*unresolved, entry.Info.Name)
}
}
func (pkgInfo *PackageInfo) GetPackageDependants(rootDir string) (dependants []string) { func (pkgInfo *PackageInfo) GetPackageDependants(rootDir string) (dependants []string) {
// Get installed package names // Get installed package names
pkgs, ok := localPackageInformation[rootDir] pkgs, ok := localPackageInformation[rootDir]
@@ -318,3 +94,64 @@ func (pkgInfo *PackageInfo) GetPackageOptionalDependants(rootDir string) (depend
return dependants return dependants
} }
type ResolvedPackage struct {
DatabaseEntry *BPMDatabaseEntry
InstallationReason InstallationReason
}
func ResolveDependencies(pkgInfo *PackageInfo, resolvedVirtualPackages map[string]string, includeRuntimeDepends, includeOptionalDepends bool, rootDir string) (resolved []ResolvedPackage, unresolved []string) {
visited := make([]string, 0)
var dfs func(resolvedPkg *PackageInfo)
dfs = func(pkgInfo *PackageInfo) {
checkDependencies := func(dependencies []string, installationReason InstallationReason) {
for _, depend := range dependencies {
// Ignore if package is already installed
if IsPackageInstalled(depend, rootDir) {
continue
} else if providers := GetVirtualPackageInfo(depend, rootDir); len(providers) > 0 {
continue
}
// Find database entry for dependency
var dependEntry *BPMDatabaseEntry
if resolvedVpkg, ok := resolvedVirtualPackages[depend]; ok {
dependEntry, _, _ = GetDatabaseEntry(resolvedVpkg)
} else if entry, _, _ := GetDatabaseEntry(depend); entry != nil {
dependEntry = entry
} else if providers := GetDatabaseVirtualPackageEntry(depend); len(providers) > 0 {
dependEntry = providers[0]
}
if dependEntry == nil {
unresolved = append(unresolved, depend)
continue
}
if !slices.Contains(visited, dependEntry.Info.Name) {
dfs(dependEntry.Info)
resolved = append(resolved, ResolvedPackage{DatabaseEntry: dependEntry, InstallationReason: installationReason})
}
}
}
visited = append(visited, pkgInfo.Name)
checkDependencies(pkgInfo.Depends, InstallationReasonDependency)
if includeRuntimeDepends {
checkDependencies(pkgInfo.RuntimeDepends, InstallationReasonDependency)
}
if pkgInfo.Type == "source" {
checkDependencies(pkgInfo.MakeDepends, InstallationReasonMakeDependency)
checkDependencies(pkgInfo.CheckDepends, InstallationReasonMakeDependency)
}
if includeOptionalDepends {
checkDependencies(pkgInfo.OptionalDepends, InstallationReasonManual)
}
}
dfs(pkgInfo)
return resolved, unresolved
}
+6 -20
View File
@@ -11,16 +11,8 @@ import (
"strings" "strings"
) )
type ReinstallMethod uint8
const (
ReinstallMethodNone ReinstallMethod = iota
ReinstallMethodSpecified ReinstallMethod = iota
ReinstallMethodAll ReinstallMethod = iota
)
// InstallPackages installs the specified packages into the given root directory by fetching them from databases or directly from local bpm archives // InstallPackages installs the specified packages into the given root directory by fetching them from databases or directly from local bpm archives
func InstallPackages(rootDir string, forceInstallationReason InstallationReason, reinstallMethod ReinstallMethod, installRuntimeDependencies, installOptionalDependencies, forceInstallation, runChecks bool, verbose bool, packages ...string) (operation *BPMOperation, err error) { func InstallPackages(rootDir string, forceInstallationReason InstallationReason, reinstallPackages bool, installRuntimeDependencies, installOptionalDependencies, forceInstallation, runChecks bool, verbose bool, packages ...string) (operation *BPMOperation, err error) {
// Setup operation struct // Setup operation struct
operation = &BPMOperation{ operation = &BPMOperation{
Actions: make([]OperationAction, 0), Actions: make([]OperationAction, 0),
@@ -45,7 +37,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
if bpmpkg.PkgInfo.Type == "source" && bpmpkg.PkgInfo.IsSplitPackage() { if bpmpkg.PkgInfo.Type == "source" && bpmpkg.PkgInfo.IsSplitPackage() {
for _, splitPkg := range bpmpkg.PkgInfo.SplitPackages { for _, splitPkg := range bpmpkg.PkgInfo.SplitPackages {
if reinstallMethod == ReinstallMethodNone && IsPackageInstalled(splitPkg.Name, rootDir) && GetPackageInfo(splitPkg.Name, rootDir).GetFullVersion() == splitPkg.GetFullVersion() { if !reinstallPackages && IsPackageInstalled(splitPkg.Name, rootDir) && GetPackageInfo(splitPkg.Name, rootDir).GetFullVersion() == splitPkg.GetFullVersion() {
continue continue
} }
@@ -69,7 +61,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
continue continue
} }
if reinstallMethod == ReinstallMethodNone && IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) && GetPackageInfo(bpmpkg.PkgInfo.Name, rootDir).GetFullVersion() == bpmpkg.PkgInfo.GetFullVersion() { if !reinstallPackages && IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) && GetPackageInfo(bpmpkg.PkgInfo.Name, rootDir).GetFullVersion() == bpmpkg.PkgInfo.GetFullVersion() {
continue continue
} }
@@ -105,7 +97,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
pkgsNotFound = append(pkgsNotFound, pkg) pkgsNotFound = append(pkgsNotFound, pkg)
continue continue
} }
if reinstallMethod == ReinstallMethodNone && IsPackageInstalled(entry.Info.Name, rootDir) && GetPackageInfo(entry.Info.Name, rootDir).GetFullVersion() == entry.Info.GetFullVersion() { if !reinstallPackages && IsPackageInstalled(entry.Info.Name, rootDir) && GetPackageInfo(entry.Info.Name, rootDir).GetFullVersion() == entry.Info.GetFullVersion() {
continue continue
} }
@@ -132,10 +124,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
} }
// Resolve dependencies // Resolve dependencies
err = operation.ResolveDependencies(reinstallMethod == ReinstallMethodAll, installRuntimeDependencies, installOptionalDependencies, verbose) operation.ResolveDependencies(installRuntimeDependencies, installOptionalDependencies)
if err != nil {
return nil, fmt.Errorf("could not resolve dependencies: %s", err)
}
if len(operation.UnresolvedDepends) != 0 { if len(operation.UnresolvedDepends) != 0 {
if !forceInstallation { if !forceInstallation {
return nil, DependencyNotFoundErr{operation.UnresolvedDepends} return nil, DependencyNotFoundErr{operation.UnresolvedDepends}
@@ -431,10 +420,7 @@ func UpdatePackages(rootDir string, syncDatabase bool, allowDowngrades bool, ins
} }
// Check for new dependencies in updated packages // Check for new dependencies in updated packages
err = operation.ResolveDependencies(false, true, installOptionalDependencies, verbose) operation.ResolveDependencies(true, installOptionalDependencies)
if err != nil {
return nil, fmt.Errorf("could not resolve dependencies: %s", err)
}
if len(operation.UnresolvedDepends) != 0 { if len(operation.UnresolvedDepends) != 0 {
if !forceInstallation { if !forceInstallation {
return nil, DependencyNotFoundErr{operation.UnresolvedDepends} return nil, DependencyNotFoundErr{operation.UnresolvedDepends}
+6 -1
View File
@@ -122,7 +122,12 @@ func GetVirtualPackageInfo(vpkg, rootDir string) []*PackageInfo {
return nil return nil
} }
return installedVirtualPackages[rootDir][vpkg] providers := installedVirtualPackages[rootDir][vpkg]
slices.SortFunc(providers, func(a, b *PackageInfo) int {
return strings.Compare(a.Name, b.Name)
})
return providers
} }
func GetPackageInfo(pkg string, rootDir string) *PackageInfo { func GetPackageInfo(pkg string, rootDir string) *PackageInfo {
+39 -18
View File
@@ -131,9 +131,9 @@ func (operation *BPMOperation) GetFinalActionSize(rootDir string) int64 {
return ret return ret
} }
func (operation *BPMOperation) ResolveDependencies(reinstallDependencies, installRuntimeDependencies, installOptionalDependencies, verbose bool) error { func (operation *BPMOperation) ResolveDependencies(installRuntimeDepends, installOptionalDependencies bool) {
pos := 0 // Discover resolved virtual packages
resolvedVirtualPkgs := make(map[string]string, 0) resolvedVirtualPackages := make(map[string]string)
for _, value := range slices.Clone(operation.Actions) { for _, value := range slices.Clone(operation.Actions) {
var pkgInfo *PackageInfo var pkgInfo *PackageInfo
if value.GetActionType() == "install" { if value.GetActionType() == "install" {
@@ -143,34 +143,55 @@ func (operation *BPMOperation) ResolveDependencies(reinstallDependencies, instal
action := value.(*FetchPackageAction) action := value.(*FetchPackageAction)
pkgInfo = action.DatabaseEntry.Info pkgInfo = action.DatabaseEntry.Info
} else { } else {
pos++
continue continue
} }
resolved, unresolved := ResolveAllPackageDependenciesFromDatabases(pkgInfo, resolvedVirtualPkgs, pkgInfo.Type == "source", pkgInfo.Type == "source" && operation.RunChecks, installRuntimeDependencies, installOptionalDependencies, !reinstallDependencies, verbose, operation.RootDir) for _, vpkg := range pkgInfo.Provides {
if _, ok := resolvedVirtualPackages[vpkg]; !ok {
resolvedVirtualPackages[vpkg] = pkgInfo.Name
}
}
}
// Discover all dependencies
pos := 0
for _, value := range slices.Clone(operation.Actions) {
var pkgInfo *PackageInfo
if value.GetActionType() == "install" {
action := value.(*InstallPackageAction)
pkgInfo = action.BpmPackage.PkgInfo
} else if value.GetActionType() == "fetch" {
action := value.(*FetchPackageAction)
pkgInfo = action.DatabaseEntry.Info
} else {
continue
}
resolved, unresolved := ResolveDependencies(pkgInfo, resolvedVirtualPackages, installRuntimeDepends, installOptionalDependencies, operation.RootDir)
// Append unresolved dependencies
operation.UnresolvedDepends = append(operation.UnresolvedDepends, unresolved...) operation.UnresolvedDepends = append(operation.UnresolvedDepends, unresolved...)
operation.UnresolvedDepends = removeDuplicates(operation.UnresolvedDepends)
for _, resolvedPkg := range resolved { for _, resolvedPkg := range resolved {
if !operation.ActionsContainPackage(resolvedPkg.PkgName) && resolvedPkg.PkgName != pkgInfo.Name { if !operation.ActionsContainPackage(resolvedPkg.DatabaseEntry.Info.Name) && resolvedPkg.DatabaseEntry.Info.Name != pkgInfo.Name {
if !reinstallDependencies && IsPackageInstalled(resolvedPkg.PkgName, operation.RootDir) {
continue
}
entry, _, err := GetDatabaseEntry(resolvedPkg.PkgName)
if err != nil {
return errors.New("could not get database entry for package (" + resolvedPkg.PkgName + ")")
}
operation.InsertActionAt(pos, &FetchPackageAction{ operation.InsertActionAt(pos, &FetchPackageAction{
InstallationReason: resolvedPkg.InstallationReason, InstallationReason: resolvedPkg.InstallationReason,
DatabaseEntry: entry, DatabaseEntry: resolvedPkg.DatabaseEntry,
}) })
pos++
for _, vpkg := range resolvedPkg.DatabaseEntry.Info.Provides {
if _, ok := resolvedVirtualPackages[vpkg]; !ok {
resolvedVirtualPackages[vpkg] = resolvedPkg.DatabaseEntry.Info.Name
} }
} }
pos++
}
return nil pos++
}
}
pos++
}
} }
func (operation *BPMOperation) RemoveNeededPackages() error { func (operation *BPMOperation) RemoveNeededPackages() error {