3 Commits
5 changed files with 51 additions and 18 deletions
+4 -8
View File
@@ -89,7 +89,6 @@ func main() {
currentFlagSet.BoolP("force", "f", false, "Bypass warnings during package installation") currentFlagSet.BoolP("force", "f", false, "Bypass warnings during package installation")
currentFlagSet.BoolP("yes", "y", false, "Enter 'yes' in all prompts") currentFlagSet.BoolP("yes", "y", false, "Enter 'yes' in all prompts")
currentFlagSet.Bool("runtime", true, "Install all runtime dependencies") 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.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.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")
@@ -142,7 +141,6 @@ func main() {
currentFlagSet.BoolP("yes", "y", false, "Enter 'yes' in all prompts") currentFlagSet.BoolP("yes", "y", false, "Enter 'yes' in all prompts")
currentFlagSet.BoolP("no-sync", "n", false, "Do not sync databases") currentFlagSet.BoolP("no-sync", "n", false, "Do not sync databases")
currentFlagSet.Bool("allow-downgrades", false, "Allow package downgrades") currentFlagSet.Bool("allow-downgrades", false, "Allow package downgrades")
currentFlagSet.BoolP("optional", "o", false, "Install all optional dependencies")
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")
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")
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Update installed packages", os.Args[2:]) setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Update installed packages", os.Args[2:])
@@ -558,7 +556,6 @@ func installPackages() {
force, _ := currentFlagSet.GetBool("force") force, _ := currentFlagSet.GetBool("force")
yesAll, _ := currentFlagSet.GetBool("yes") yesAll, _ := currentFlagSet.GetBool("yes")
installRuntime, _ := currentFlagSet.GetBool("runtime") installRuntime, _ := currentFlagSet.GetBool("runtime")
installOptional, _ := currentFlagSet.GetBool("optional")
installationReason, _ := currentFlagSet.GetString("installation-reason") installationReason, _ := currentFlagSet.GetString("installation-reason")
reinstallPackages, _ := currentFlagSet.GetBool("reinstall") reinstallPackages, _ := currentFlagSet.GetBool("reinstall")
skipChecks, _ := currentFlagSet.GetBool("skip-checks") skipChecks, _ := currentFlagSet.GetBool("skip-checks")
@@ -620,7 +617,7 @@ func installPackages() {
} }
// Create installation operation // Create installation operation
operation, err := bpmlib.InstallPackages(rootDir, ir, reinstallPackages, installRuntime, installOptional, force, !skipChecks, verbose, packages...) operation, err := bpmlib.InstallPackages(rootDir, ir, reinstallPackages, installRuntime, 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
@@ -705,7 +702,7 @@ func installPackages() {
} }
// Show optional dependencies // Show optional dependencies
if !installOptional && len(optionalDepends) != 0 { if len(optionalDepends) != 0 {
// List optional dependencies // List optional dependencies
fmt.Println("The following optional dependenices have been discovered:") fmt.Println("The following optional dependenices have been discovered:")
for dependant, depends := range optionalDepends { for dependant, depends := range optionalDepends {
@@ -993,7 +990,6 @@ func updatePackages() {
yesAll, _ := currentFlagSet.GetBool("yes") yesAll, _ := currentFlagSet.GetBool("yes")
noSync, _ := currentFlagSet.GetBool("no-sync") noSync, _ := currentFlagSet.GetBool("no-sync")
allowDowngrades, _ := currentFlagSet.GetBool("allow-downgrades") allowDowngrades, _ := currentFlagSet.GetBool("allow-downgrades")
installOptional, _ := currentFlagSet.GetBool("optional")
skipChecks, _ := currentFlagSet.GetBool("skip-checks") skipChecks, _ := currentFlagSet.GetBool("skip-checks")
compilationJobs, _ := currentFlagSet.GetInt("jobs") compilationJobs, _ := currentFlagSet.GetInt("jobs")
@@ -1041,7 +1037,7 @@ func updatePackages() {
} }
// Create update operation // Create update operation
operation, err := bpmlib.UpdatePackages(rootDir, !noSync, allowDowngrades, installOptional, force, !skipChecks, verbose) operation, err := bpmlib.UpdatePackages(rootDir, !noSync, allowDowngrades, force, !skipChecks, verbose)
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
@@ -1126,7 +1122,7 @@ func updatePackages() {
} }
// Show optional dependencies // Show optional dependencies
if !installOptional && len(optionalDepends) != 0 { if len(optionalDepends) != 0 {
// List optional dependencies // List optional dependencies
fmt.Println("The following optional dependenices have been discovered:") fmt.Println("The following optional dependenices have been discovered:")
for dependant, depends := range optionalDepends { for dependant, depends := range optionalDepends {
+40
View File
@@ -358,6 +358,35 @@ func (entry *BPMDatabaseEntry) GetEntryOptionalDependants() (dependants []string
return dependants return dependants
} }
func (entry *BPMDatabaseEntry) GetEntryMakeDependants() (dependants []string) {
dependantsMap := make(map[string][]string)
for _, db := range BPMDatabases {
for _, e := range db.Entries {
if slices.Contains(e.Info.MakeDepends, entry.Info.Name) {
dependantsMap[e.Info.Name] = append(dependantsMap[e.Info.Name], e.Database.Name)
}
}
}
// Get keys
keySlice := slices.Collect(maps.Keys(dependantsMap))
slices.Sort(keySlice)
// Add all dependant entries to slice in alphabetical order
for _, entryName := range keySlice {
dbs := dependantsMap[entryName]
if len(dbs) > 1 {
for _, db := range dbs {
dependants = append(dependants, db+"/"+entryName)
}
} else {
dependants = append(dependants, entryName)
}
}
return dependants
}
func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string, showBytes bool) string { func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string, showBytes bool) string {
builder := strings.Builder{} builder := strings.Builder{}
builderWriteStringNotEmpty := func(label string, value string) { builderWriteStringNotEmpty := func(label string, value string) {
@@ -458,6 +487,7 @@ func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string, showBytes bool
} }
builderWriteArray("Dependant packages", entry.GetEntryDependants(), true) builderWriteArray("Dependant packages", entry.GetEntryDependants(), true)
builderWriteArray("Optionally dependant packages", entry.GetEntryOptionalDependants(), true) builderWriteArray("Optionally dependant packages", entry.GetEntryOptionalDependants(), true)
builderWriteArray("Make dependant packages", entry.GetEntryMakeDependants(), true)
// Other package relations // Other package relations
builderWriteArray("Conflicting packages", entry.Info.Conflicts, true) builderWriteArray("Conflicting packages", entry.Info.Conflicts, true)
@@ -490,6 +520,16 @@ func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string, showBytes bool
builder.WriteString("Installation reason: " + installationReasonString + "\n") builder.WriteString("Installation reason: " + installationReasonString + "\n")
} }
// Download size
downloadSize := entry.DownloadSize
var downloadSizeStr string
if showBytes {
downloadSizeStr = strconv.FormatInt(downloadSize, 10)
} else {
downloadSizeStr = BytesToHumanReadable(downloadSize)
}
builder.WriteString("Download size: " + downloadSizeStr + "\n")
// Installed size // Installed size
if entry.Info.Type == "binary" { if entry.Info.Type == "binary" {
installedSize := entry.InstalledSize installedSize := entry.InstalledSize
+1 -4
View File
@@ -100,7 +100,7 @@ type ResolvedPackage struct {
InstallationReason InstallationReason InstallationReason InstallationReason
} }
func ResolveDependencies(pkgInfo *PackageInfo, resolvedVirtualPackages map[string]string, includeRuntimeDepends, includeOptionalDepends bool, rootDir string) (resolved []ResolvedPackage, unresolved []string) { func ResolveDependencies(pkgInfo *PackageInfo, resolvedVirtualPackages map[string]string, includeRuntimeDepends bool, rootDir string) (resolved []ResolvedPackage, unresolved []string) {
visited := make([]string, 0) visited := make([]string, 0)
var dfs func(resolvedPkg *PackageInfo) var dfs func(resolvedPkg *PackageInfo)
@@ -146,9 +146,6 @@ func ResolveDependencies(pkgInfo *PackageInfo, resolvedVirtualPackages map[strin
checkDependencies(pkgInfo.MakeDepends, InstallationReasonMakeDependency) checkDependencies(pkgInfo.MakeDepends, InstallationReasonMakeDependency)
checkDependencies(pkgInfo.CheckDepends, InstallationReasonMakeDependency) checkDependencies(pkgInfo.CheckDepends, InstallationReasonMakeDependency)
} }
if includeOptionalDepends {
checkDependencies(pkgInfo.OptionalDepends, InstallationReasonManual)
}
} }
dfs(pkgInfo) dfs(pkgInfo)
+4 -4
View File
@@ -12,7 +12,7 @@ import (
) )
// 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, reinstallPackages bool, installRuntimeDependencies, installOptionalDependencies, forceInstallation, runChecks bool, verbose bool, packages ...string) (operation *BPMOperation, err error) { func InstallPackages(rootDir string, forceInstallationReason InstallationReason, reinstallPackages bool, installRuntimeDependencies, 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),
@@ -124,7 +124,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
} }
// Resolve dependencies // Resolve dependencies
operation.ResolveDependencies(installRuntimeDependencies, installOptionalDependencies) operation.ResolveDependencies(installRuntimeDependencies)
if len(operation.UnresolvedDepends) != 0 { if len(operation.UnresolvedDepends) != 0 {
if !forceInstallation { if !forceInstallation {
return nil, DependencyNotFoundErr{operation.UnresolvedDepends} return nil, DependencyNotFoundErr{operation.UnresolvedDepends}
@@ -355,7 +355,7 @@ func CleanupCache(rootDir string, cleanupCompilationFiles, cleanupCompiledPackag
} }
// UpdatePackages fetches the newest versions of all installed packages from // UpdatePackages fetches the newest versions of all installed packages from
func UpdatePackages(rootDir string, syncDatabase bool, allowDowngrades bool, installOptionalDependencies, forceInstallation, runChecks, verbose bool) (operation *BPMOperation, err error) { func UpdatePackages(rootDir string, syncDatabase, allowDowngrades, forceInstallation, runChecks, verbose bool) (operation *BPMOperation, err error) {
// Sync databases // Sync databases
if syncDatabase { if syncDatabase {
err := SyncDatabase(verbose) err := SyncDatabase(verbose)
@@ -420,7 +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
operation.ResolveDependencies(true, installOptionalDependencies) operation.ResolveDependencies(true)
if len(operation.UnresolvedDepends) != 0 { if len(operation.UnresolvedDepends) != 0 {
if !forceInstallation { if !forceInstallation {
return nil, DependencyNotFoundErr{operation.UnresolvedDepends} return nil, DependencyNotFoundErr{operation.UnresolvedDepends}
+2 -2
View File
@@ -131,7 +131,7 @@ func (operation *BPMOperation) GetFinalActionSize(rootDir string) int64 {
return ret return ret
} }
func (operation *BPMOperation) ResolveDependencies(installRuntimeDepends, installOptionalDependencies bool) { func (operation *BPMOperation) ResolveDependencies(installRuntimeDepends bool) {
// Discover resolved virtual packages // Discover resolved virtual packages
resolvedVirtualPackages := make(map[string]string) resolvedVirtualPackages := make(map[string]string)
for _, value := range slices.Clone(operation.Actions) { for _, value := range slices.Clone(operation.Actions) {
@@ -167,7 +167,7 @@ func (operation *BPMOperation) ResolveDependencies(installRuntimeDepends, instal
continue continue
} }
resolved, unresolved := ResolveDependencies(pkgInfo, resolvedVirtualPackages, installRuntimeDepends, installOptionalDependencies, operation.RootDir) resolved, unresolved := ResolveDependencies(pkgInfo, resolvedVirtualPackages, installRuntimeDepends, operation.RootDir)
// Append unresolved dependencies // Append unresolved dependencies
operation.UnresolvedDepends = append(operation.UnresolvedDepends, unresolved...) operation.UnresolvedDepends = append(operation.UnresolvedDepends, unresolved...)