From 72f17f895481fe9c98d79ced6f033b83ddfac885 Mon Sep 17 00:00:00 2001 From: EnumDev Date: Tue, 6 Jan 2026 19:35:42 +0200 Subject: [PATCH] Rework runtime dependency system --- src/bpm/main.go | 10 +++++--- src/bpmlib/compilation.go | 4 --- src/bpmlib/databases.go | 1 + src/bpmlib/dependencies.go | 50 +++++++++++++++++++++++++++++--------- src/bpmlib/general.go | 6 ++--- src/bpmlib/operations.go | 6 ++--- src/bpmlib/packages.go | 1 + 7 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/bpm/main.go b/src/bpm/main.go index 24244fd..69f625c 100644 --- a/src/bpm/main.go +++ b/src/bpm/main.go @@ -87,6 +87,7 @@ func main() { currentFlagSet.BoolP("verbose", "v", false, "Show additional information about the current operation") currentFlagSet.BoolP("force", "f", false, "Bypass warnings during package installation") currentFlagSet.BoolP("yes", "y", false, "Enter 'yes' in all prompts") + currentFlagSet.Bool("runtime", true, "Install all runtime 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.BoolP("reinstall", "r", false, "Reinstall the specified packages") @@ -480,6 +481,7 @@ func installPackages() { verbose, _ := currentFlagSet.GetBool("verbose") force, _ := currentFlagSet.GetBool("force") yesAll, _ := currentFlagSet.GetBool("yes") + installRuntime, _ := currentFlagSet.GetBool("runtime") installOptional, _ := currentFlagSet.GetBool("optional") installationReason, _ := currentFlagSet.GetString("installation-reason") reinstall, _ := currentFlagSet.GetBool("reinstall") @@ -543,7 +545,7 @@ func installPackages() { } // Create installation operation - operation, err := bpmlib.InstallPackages(rootDir, ir, reinstallMethod, installOptional, force, verbose, packages...) + operation, err := bpmlib.InstallPackages(rootDir, ir, reinstallMethod, installRuntime, installOptional, force, verbose, packages...) if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) { log.Printf("Error: %s", err) exitCode = 1 @@ -1163,9 +1165,9 @@ func compilePackage() { return } - // Get direct runtime and make dependencies + // Get direct common and make dependencies totalDepends := make([]string, 0) - for _, depend := range bpmpkg.PkgInfo.GetDependencies(true, false) { + for _, depend := range bpmpkg.PkgInfo.GetDependencies(true, false, false) { if !slices.Contains(totalDepends, depend.PkgName) { totalDepends = append(totalDepends, depend.PkgName) } @@ -1198,7 +1200,7 @@ func compilePackage() { } // Run 'bpm install' using the set privilege escalator command - args := []string{executable, "install", "--installation-reason=make-dependency"} + args := []string{executable, "install", "--runtime=false", "--installation-reason=make-dependency"} args = append(args, unmetDepends...) cmd := exec.Command(bpmlib.CompilationBPMConfig.PrivilegeEscalatorCmd, args...) if yesAll { diff --git a/src/bpmlib/compilation.go b/src/bpmlib/compilation.go index 36bc9f5..5b9e143 100644 --- a/src/bpmlib/compilation.go +++ b/src/bpmlib/compilation.go @@ -344,10 +344,6 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks, k pkgInfo.Arch = pkg.OutputArch pkgInfo.OutputArch = "" - // Add runtime dependencies to common dependencies - pkgInfo.Depends = removeDuplicates(append(pkgInfo.Depends, pkgInfo.RuntimeDepends...)) - pkgInfo.RuntimeDepends = nil - // Remove split package and downloads fields pkgInfo.SplitPackages = nil pkgInfo.Downloads = nil diff --git a/src/bpmlib/databases.go b/src/bpmlib/databases.go index fe8ff3a..17343e1 100644 --- a/src/bpmlib/databases.go +++ b/src/bpmlib/databases.go @@ -356,6 +356,7 @@ func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string, humanReadableS if entry.Info.Type == "source" { appendArray("Make Dependencies", entry.Info.MakeDepends, true) } + appendArray("Runtime dependencies", entry.Info.RuntimeDepends, true) appendArray("Optional dependencies", entry.Info.OptionalDepends, true) dependants := entry.GetEntryDependants() if len(dependants) > 0 { diff --git a/src/bpmlib/dependencies.go b/src/bpmlib/dependencies.go index bb9195a..26c6a2c 100644 --- a/src/bpmlib/dependencies.go +++ b/src/bpmlib/dependencies.go @@ -10,7 +10,7 @@ type pkgInstallationReason struct { InstallationReason InstallationReason } -func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeOptionalDepends bool) []pkgInstallationReason { +func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeRuntimeDepends, includeOptionalDepends bool) []pkgInstallationReason { allDepends := make([]pkgInstallationReason, 0) for _, depend := range pkgInfo.Depends { @@ -35,6 +35,18 @@ func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeOptionalD } } } + 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 { @@ -56,23 +68,23 @@ func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeOptionalD return allDepends } -func (pkgInfo *PackageInfo) GetDependenciesRecursive(includeMakeDepends bool, rootDir string) (resolved []string) { +func (pkgInfo *PackageInfo) GetDependenciesRecursive(includeRuntimeDepends, includeMakeDepends bool, rootDir string) (resolved []string) { // Initialize slices resolved = make([]string, 0) unresolved := make([]string, 0) // Call unexported function - pkgInfo.getDependenciesRecursive(&resolved, &unresolved, includeMakeDepends, rootDir) + pkgInfo.getDependenciesRecursive(&resolved, &unresolved, includeRuntimeDepends, includeMakeDepends, rootDir) return resolved } -func (pkgInfo *PackageInfo) getDependenciesRecursive(resolved *[]string, unresolved *[]string, includeMakeDepends bool, rootDir string) { +func (pkgInfo *PackageInfo) getDependenciesRecursive(resolved *[]string, unresolved *[]string, includeRuntimeDepends, includeMakeDepends 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, false) { + for _, pkgIR := range pkgInfo.GetDependencies(includeMakeDepends, includeRuntimeDepends, false) { depend := pkgIR.PkgName if isVirtual, p := IsVirtualPackage(depend, rootDir); isVirtual { @@ -91,7 +103,7 @@ func (pkgInfo *PackageInfo) getDependenciesRecursive(resolved *[]string, unresol dependInfo := GetPackageInfo(depend, rootDir) if dependInfo != nil { - dependInfo.getDependenciesRecursive(resolved, unresolved, includeMakeDepends, rootDir) + dependInfo.getDependenciesRecursive(resolved, unresolved, includeRuntimeDepends, includeMakeDepends, rootDir) } } } @@ -101,13 +113,13 @@ func (pkgInfo *PackageInfo) getDependenciesRecursive(resolved *[]string, unresol *unresolved = stringSliceRemove(*unresolved, pkgInfo.Name) } -func ResolveAllPackageDependenciesFromDatabases(pkgInfo *PackageInfo, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) (resolved []pkgInstallationReason, unresolved []string) { +func ResolveAllPackageDependenciesFromDatabases(pkgInfo *PackageInfo, checkMake, checkRuntime, checkOptional, ignoreInstalled, verbose bool, rootDir string) (resolved []pkgInstallationReason, unresolved []string) { // Initialize slices resolved = make([]pkgInstallationReason, 0) unresolved = make([]string, 0) // Call unexported function - resolvePackageDependenciesFromDatabase(&resolved, &unresolved, pkgInfo, checkMake, checkOptional, ignoreInstalled, verbose, rootDir) + resolvePackageDependenciesFromDatabase(&resolved, &unresolved, pkgInfo, checkMake, checkRuntime, checkOptional, ignoreInstalled, verbose, rootDir) // Remove main package from unresolved slice unresolved = stringSliceRemove(unresolved, pkgInfo.Name) @@ -115,12 +127,12 @@ func ResolveAllPackageDependenciesFromDatabases(pkgInfo *PackageInfo, checkMake, return resolved, unresolved } -func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, unresolved *[]string, pkgInfo *PackageInfo, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) { +func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, unresolved *[]string, pkgInfo *PackageInfo, checkMake, checkRuntime, checkOptional, ignoreInstalled, verbose bool, rootDir string) { // Add current package name to unresolved slice *unresolved = append(*unresolved, pkgInfo.Name) // Loop through all dependencies - for _, pkgIR := range pkgInfo.GetDependencies(pkgInfo.Type == "source", checkOptional) { + for _, pkgIR := range pkgInfo.GetDependencies(pkgInfo.Type == "source", checkRuntime, checkOptional) { // Skip dependency if it has already been resolved if slices.ContainsFunc(*resolved, func(p pkgInstallationReason) bool { return p.PkgName == pkgIR.PkgName @@ -160,7 +172,7 @@ func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, u } // Resolve the dependencies of this dependency - resolvePackageDependenciesFromDatabase(resolved, unresolved, entry.Info, checkMake, false, ignoreInstalled, verbose, rootDir) + resolvePackageDependenciesFromDatabase(resolved, unresolved, entry.Info, checkMake, checkRuntime, false, ignoreInstalled, verbose, rootDir) // Move dependency from the unresolved slice to the resolved slice if !slices.ContainsFunc(*resolved, func(p pkgInstallationReason) bool { @@ -197,6 +209,14 @@ func (pkgInfo *PackageInfo) GetPackageDependants(rootDir string) (dependants []s continue } + // Add installed package to list if its runtime dependencies include pkgName + if slices.ContainsFunc(installedPkg.RuntimeDepends, func(n string) bool { + return n == pkgInfo.Name + }) { + dependants = append(dependants, installedPkg.Name) + continue + } + // Loop through each virtual package for _, vpkg := range pkgInfo.Provides { // Add installed package to list if its dependencies contain a provided virtual package @@ -206,6 +226,14 @@ func (pkgInfo *PackageInfo) GetPackageDependants(rootDir string) (dependants []s dependants = append(dependants, installedPkg.Name) break } + + // Add installed package to list if its runtime dependencies contain a provided virtual package + if slices.ContainsFunc(installedPkg.RuntimeDepends, func(n string) bool { + return n == vpkg + }) { + dependants = append(dependants, installedPkg.Name) + break + } } } diff --git a/src/bpmlib/general.go b/src/bpmlib/general.go index 3a25aca..ce37c1f 100644 --- a/src/bpmlib/general.go +++ b/src/bpmlib/general.go @@ -20,7 +20,7 @@ const ( ) // 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, installOptionalDependencies, forceInstallation, verbose bool, packages ...string) (operation *BPMOperation, err error) { +func InstallPackages(rootDir string, forceInstallationReason InstallationReason, reinstallMethod ReinstallMethod, installRuntimeDependencies, installOptionalDependencies, forceInstallation, verbose bool, packages ...string) (operation *BPMOperation, err error) { // Setup operation struct operation = &BPMOperation{ Actions: make([]OperationAction, 0), @@ -131,7 +131,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason, } // Resolve dependencies - err = operation.ResolveDependencies(reinstallMethod == ReinstallMethodAll, installOptionalDependencies, verbose) + err = operation.ResolveDependencies(reinstallMethod == ReinstallMethodAll, installRuntimeDependencies, installOptionalDependencies, verbose) if err != nil { return nil, fmt.Errorf("could not resolve dependencies: %s", err) } @@ -429,7 +429,7 @@ func UpdatePackages(rootDir string, syncDatabase bool, allowDowngrades bool, ins } // Check for new dependencies in updated packages - err = operation.ResolveDependencies(false, installOptionalDependencies, verbose) + err = operation.ResolveDependencies(false, true, installOptionalDependencies, verbose) if err != nil { return nil, fmt.Errorf("could not resolve dependencies: %s", err) } diff --git a/src/bpmlib/operations.go b/src/bpmlib/operations.go index c4824f3..848a849 100644 --- a/src/bpmlib/operations.go +++ b/src/bpmlib/operations.go @@ -129,7 +129,7 @@ func (operation *BPMOperation) GetFinalActionSize(rootDir string) int64 { return ret } -func (operation *BPMOperation) ResolveDependencies(reinstallDependencies, installOptionalDependencies, verbose bool) error { +func (operation *BPMOperation) ResolveDependencies(reinstallDependencies, installRuntimeDependencies, installOptionalDependencies, verbose bool) error { pos := 0 for _, value := range slices.Clone(operation.Actions) { var pkgInfo *PackageInfo @@ -144,7 +144,7 @@ func (operation *BPMOperation) ResolveDependencies(reinstallDependencies, instal continue } - resolved, unresolved := ResolveAllPackageDependenciesFromDatabases(pkgInfo, pkgInfo.Type == "source", installOptionalDependencies, !reinstallDependencies, verbose, operation.RootDir) + resolved, unresolved := ResolveAllPackageDependenciesFromDatabases(pkgInfo, pkgInfo.Type == "source", installRuntimeDependencies, installOptionalDependencies, !reinstallDependencies, verbose, operation.RootDir) operation.UnresolvedDepends = append(operation.UnresolvedDepends, unresolved...) @@ -230,7 +230,7 @@ func (operation *BPMOperation) Cleanup(cleanupMakeDepends bool) error { } keepPackages = append(keepPackages, pkg.Name) - resolved := pkg.GetDependenciesRecursive(!cleanupMakeDepends, operation.RootDir) + resolved := pkg.GetDependenciesRecursive(true, !cleanupMakeDepends, operation.RootDir) for _, value := range resolved { if !slices.Contains(keepPackages, value) && !slices.Contains(MainBPMConfig.IgnorePackages, value) { keepPackages = append(keepPackages, value) diff --git a/src/bpmlib/packages.go b/src/bpmlib/packages.go index dba7558..c30d80d 100644 --- a/src/bpmlib/packages.go +++ b/src/bpmlib/packages.go @@ -567,6 +567,7 @@ func (pkgInfo *PackageInfo) CreateReadableInfo(rootDir string) string { appendArray("Runtime Dependencies", pkgInfo.RuntimeDepends) appendArray("Make Dependencies", pkgInfo.MakeDepends) } + appendArray("Runtime dependencies", pkgInfo.RuntimeDepends) appendArray("Optional dependencies", pkgInfo.OptionalDepends) dependants := pkgInfo.GetPackageDependants(rootDir) if len(dependants) > 0 {