2 Commits
Author SHA1 Message Date
EnumDev 72f17f8954 Rework runtime dependency system 2026-01-06 19:35:42 +02:00
EnumDev fd646a820d Add 'runtime_depends' field to package info 2026-01-04 14:40:55 +02:00
6 changed files with 56 additions and 21 deletions
+6 -4
View File
@@ -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 {
+1
View File
@@ -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 {
+39 -11
View File
@@ -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
}
}
}
+3 -3
View File
@@ -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)
}
+3 -3
View File
@@ -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)
+4
View File
@@ -37,6 +37,7 @@ type PackageInfo struct {
Type string `yaml:"type,omitempty"`
Keep []string `yaml:"keep,omitempty"`
Depends []string `yaml:"depends,omitempty"`
RuntimeDepends []string `yaml:"runtime_depends,omitempty"`
OptionalDepends []string `yaml:"optional_depends,omitempty"`
MakeDepends []string `yaml:"make_depends,omitempty"`
Conflicts []string `yaml:"conflicts,omitempty"`
@@ -457,6 +458,7 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) {
OutputArch: GetArch(),
Keep: make([]string, 0),
Depends: make([]string, 0),
RuntimeDepends: make([]string, 0),
MakeDepends: make([]string, 0),
OptionalDepends: make([]string, 0),
Conflicts: make([]string, 0),
@@ -562,8 +564,10 @@ func (pkgInfo *PackageInfo) CreateReadableInfo(rootDir string) string {
ret = append(ret, "Type: "+pkgInfo.Type)
appendArray("Dependencies", pkgInfo.Depends)
if pkgInfo.Type == "source" {
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 {