Add "make_dependency" installation reason

This commit is contained in:
EnumDev 2025-05-23 14:16:52 +03:00
parent 966d351a80
commit 458c091ac2
7 changed files with 149 additions and 99 deletions

View File

@ -1,6 +1,7 @@
ignore_packages: [] ignore_packages: []
privilege_escalator_cmd: "sudo" privilege_escalator_cmd: "sudo"
compilation_env: [] compilation_env: []
cleanup_make_dependencies: true
databases: databases:
- name: example-database - name: example-database
source: https://my-database.xyz/ source: https://my-database.xyz/

View File

@ -44,6 +44,7 @@ var installSrcPkgDepends = false
var skipChecks = false var skipChecks = false
var outputDirectory = "" var outputDirectory = ""
var cleanupDependencies = false var cleanupDependencies = false
var cleanupMakeDependencies = false
var cleanupCompilationFiles = false var cleanupCompilationFiles = false
var cleanupCompiledPackages = false var cleanupCompiledPackages = false
var cleanupFetchedPackages = false var cleanupFetchedPackages = false
@ -249,12 +250,14 @@ func resolveCommand() {
} }
// Check if installationReason argument is valid // Check if installationReason argument is valid
ir := bpmlib.InstallationReasonUnknown ir := bpmlib.InstallationReasonManual
switch installationReason { switch installationReason {
case "manual": case "manual":
ir = bpmlib.InstallationReasonManual ir = bpmlib.InstallationReasonManual
case "dependency": case "dependency":
ir = bpmlib.InstallationReasonDependency ir = bpmlib.InstallationReasonDependency
case "make-dependency":
ir = bpmlib.InstallationReasonMakeDependency
case "": case "":
default: default:
log.Fatalf("Error: %s is not a valid installation reason", installationReason) log.Fatalf("Error: %s is not a valid installation reason", installationReason)
@ -467,7 +470,7 @@ func resolveCommand() {
log.Fatalf("Error: could not complete cache cleanup: %s", err) log.Fatalf("Error: could not complete cache cleanup: %s", err)
} }
if cleanupDependencies { if cleanupDependencies || cleanupMakeDependencies {
// Read local databases // Read local databases
err := bpmlib.ReadLocalDatabaseFiles() err := bpmlib.ReadLocalDatabaseFiles()
if err != nil { if err != nil {
@ -475,7 +478,7 @@ func resolveCommand() {
} }
// Create cleanup operation // Create cleanup operation
operation, err := bpmlib.CleanupPackages(rootDir) operation, err := bpmlib.CleanupPackages(cleanupMakeDependencies, rootDir)
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.Fatalf("Error: %s", err) log.Fatalf("Error: %s", err)
} else if err != nil { } else if err != nil {
@ -595,7 +598,7 @@ func resolveCommand() {
// Get direct runtime and make dependencies // Get direct runtime and make dependencies
totalDepends := make([]string, 0) totalDepends := make([]string, 0)
for _, depend := range bpmpkg.PkgInfo.GetDependencies(true, false) { for depend := range bpmpkg.PkgInfo.GetDependencies(true, false) {
if !slices.Contains(totalDepends, depend) { if !slices.Contains(totalDepends, depend) {
totalDepends = append(totalDepends, depend) totalDepends = append(totalDepends, depend)
} }
@ -624,7 +627,7 @@ func resolveCommand() {
} }
// Run 'bpm install' using the set privilege escalator command // Run 'bpm install' using the set privilege escalator command
args := []string{executable, "install", "--installation-reason=dependency"} args := []string{executable, "install", "--installation-reason=make-dependency"}
args = append(args, unmetDepends...) args = append(args, unmetDepends...)
cmd := exec.Command(bpmlib.BPMConfig.PrivilegeEscalatorCmd, args...) cmd := exec.Command(bpmlib.BPMConfig.PrivilegeEscalatorCmd, args...)
if yesAll { if yesAll {
@ -777,6 +780,7 @@ func printHelp() {
fmt.Println(" -R=<path> lets you define the root path which will be used") fmt.Println(" -R=<path> lets you define the root path which will be used")
fmt.Println(" -y skips the confirmation prompt") fmt.Println(" -y skips the confirmation prompt")
fmt.Println(" --depends performs a dependency cleanup") fmt.Println(" --depends performs a dependency cleanup")
fmt.Println(" --make-depends performs a make dependency cleanup")
fmt.Println(" --compilation-files performs a cleanup of compilation files") fmt.Println(" --compilation-files performs a cleanup of compilation files")
fmt.Println(" --compiled-pkgs performs a cleanup of compilation compiled binary packages") fmt.Println(" --compiled-pkgs performs a cleanup of compilation compiled binary packages")
fmt.Println(" --fetched-pkgs performs a cleanup of fetched packages from databases") fmt.Println(" --fetched-pkgs performs a cleanup of fetched packages from databases")
@ -843,6 +847,7 @@ func resolveFlags() {
cleanupFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing") cleanupFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing")
cleanupFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts") cleanupFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts")
cleanupFlagSet.BoolVar(&cleanupDependencies, "depends", false, "Perform a dependency cleanup") cleanupFlagSet.BoolVar(&cleanupDependencies, "depends", false, "Perform a dependency cleanup")
cleanupFlagSet.BoolVar(&cleanupMakeDependencies, "make-depends", false, "Perform a make dependency cleanup")
cleanupFlagSet.BoolVar(&cleanupCompilationFiles, "compilation-files", false, "Perform a cleanup of compilation files") cleanupFlagSet.BoolVar(&cleanupCompilationFiles, "compilation-files", false, "Perform a cleanup of compilation files")
cleanupFlagSet.BoolVar(&cleanupCompiledPackages, "compiled-pkgs", false, "Perform a cleanup of compilation compiled binary packages") cleanupFlagSet.BoolVar(&cleanupCompiledPackages, "compiled-pkgs", false, "Perform a cleanup of compilation compiled binary packages")
cleanupFlagSet.BoolVar(&cleanupFetchedPackages, "fetched-pkgs", false, "Perform a cleanup of fetched packages from databases") cleanupFlagSet.BoolVar(&cleanupFetchedPackages, "fetched-pkgs", false, "Perform a cleanup of fetched packages from databases")
@ -858,8 +863,18 @@ func resolveFlags() {
compileFlagSet.StringVar(&outputDirectory, "o", "", "Set output directory") compileFlagSet.StringVar(&outputDirectory, "o", "", "Set output directory")
compileFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing") compileFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing")
compileFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts") compileFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts")
compileFlagSet.Usage = printHelp compileFlagSet.Usage = printHelp
isFlagSet := func(flagSet *flag.FlagSet, name string) bool {
found := false
flagSet.Visit(func(f *flag.Flag) {
if f.Name == name {
found = true
}
})
return found
}
if len(os.Args[1:]) <= 0 { if len(os.Args[1:]) <= 0 {
subcommand = "help" subcommand = "help"
} else { } else {
@ -906,8 +921,9 @@ func resolveFlags() {
if err != nil { if err != nil {
return return
} }
if !cleanupDependencies && !cleanupCompilationFiles && !cleanupCompiledPackages && !cleanupFetchedPackages { if !isFlagSet(cleanupFlagSet, "depends") && !isFlagSet(cleanupFlagSet, "make-depends") && !isFlagSet(cleanupFlagSet, "compilation-files") && !isFlagSet(cleanupFlagSet, "compiled-pkgs") && !isFlagSet(cleanupFlagSet, "fetched-pkgs") {
cleanupDependencies = true cleanupDependencies = true
cleanupMakeDependencies = bpmlib.BPMConfig.CleanupMakeDependencies
cleanupCompilationFiles = true cleanupCompilationFiles = true
cleanupCompiledPackages = true cleanupCompiledPackages = true
cleanupFetchedPackages = true cleanupFetchedPackages = true

View File

@ -6,10 +6,11 @@ import (
) )
type BPMConfigStruct struct { type BPMConfigStruct struct {
IgnorePackages []string `yaml:"ignore_packages"` IgnorePackages []string `yaml:"ignore_packages"`
PrivilegeEscalatorCmd string `yaml:"privilege_escalator_cmd"` PrivilegeEscalatorCmd string `yaml:"privilege_escalator_cmd"`
CompilationEnvironment []string `yaml:"compilation_env"` CompilationEnvironment []string `yaml:"compilation_env"`
Databases []*BPMDatabase `yaml:"databases"` CleanupMakeDependencies bool `yaml:"cleanup_make_dependencies"`
Databases []*BPMDatabase `yaml:"databases"`
} }
var BPMConfig BPMConfigStruct var BPMConfig BPMConfigStruct
@ -24,7 +25,9 @@ func ReadConfig() (err error) {
return err return err
} }
BPMConfig = BPMConfigStruct{} BPMConfig = BPMConfigStruct{
CleanupMakeDependencies: true,
}
err = yaml.Unmarshal(bytes, &BPMConfig) err = yaml.Unmarshal(bytes, &BPMConfig)
if err != nil { if err != nil {
return err return err

View File

@ -6,14 +6,25 @@ import (
"slices" "slices"
) )
func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeOptionalDepends bool) []string { func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeOptionalDepends bool) map[string]InstallationReason {
allDepends := make([]string, 0) allDepends := make(map[string]InstallationReason)
allDepends = append(allDepends, pkgInfo.Depends...)
if includeMakeDepends { for _, depend := range pkgInfo.Depends {
allDepends = append(allDepends, pkgInfo.MakeDepends...) allDepends[depend] = InstallationReasonDependency
} }
if includeOptionalDepends { if includeOptionalDepends {
allDepends = append(allDepends, pkgInfo.OptionalDepends...) for _, depend := range pkgInfo.OptionalDepends {
if _, ok := allDepends[depend]; !ok {
allDepends[depend] = InstallationReasonDependency
}
}
}
if includeMakeDepends {
for _, depend := range pkgInfo.MakeDepends {
if _, ok := allDepends[depend]; !ok {
allDepends[depend] = InstallationReasonMakeDependency
}
}
} }
return allDepends return allDepends
} }
@ -34,7 +45,10 @@ func (pkgInfo *PackageInfo) getAllDependencies(resolved *[]string, unresolved *[
*unresolved = append(*unresolved, pkgInfo.Name) *unresolved = append(*unresolved, pkgInfo.Name)
// Loop through all dependencies // Loop through all dependencies
for _, depend := range pkgInfo.GetDependencies(includeMakeDepends, includeOptionalDepends) { for depend := range pkgInfo.GetDependencies(includeMakeDepends, includeOptionalDepends) {
if isVirtual, p := IsVirtualPackage(depend, rootDir); isVirtual {
depend = p
}
if !slices.Contains(*resolved, depend) { if !slices.Contains(*resolved, depend) {
// Add current dependency to resolved slice when circular dependency is detected // Add current dependency to resolved slice when circular dependency is detected
if slices.Contains(*unresolved, depend) { if slices.Contains(*unresolved, depend) {
@ -44,13 +58,7 @@ func (pkgInfo *PackageInfo) getAllDependencies(resolved *[]string, unresolved *[
continue continue
} }
var dependInfo *PackageInfo dependInfo := GetPackageInfo(depend, rootDir)
if isVirtual, p := IsVirtualPackage(depend, rootDir); isVirtual {
dependInfo = GetPackageInfo(p, rootDir)
} else {
dependInfo = GetPackageInfo(depend, rootDir)
}
if dependInfo != nil { if dependInfo != nil {
dependInfo.getAllDependencies(resolved, unresolved, includeMakeDepends, includeOptionalDepends, rootDir) dependInfo.getAllDependencies(resolved, unresolved, includeMakeDepends, includeOptionalDepends, rootDir)
@ -63,31 +71,31 @@ func (pkgInfo *PackageInfo) getAllDependencies(resolved *[]string, unresolved *[
*unresolved = stringSliceRemove(*unresolved, pkgInfo.Name) *unresolved = stringSliceRemove(*unresolved, pkgInfo.Name)
} }
func ResolvePackageDependenciesFromDatabases(pkgInfo *PackageInfo, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) (resolved []string, unresolved []string) { func ResolveAllPackageDependenciesFromDatabases(pkgInfo *PackageInfo, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) (resolved map[string]InstallationReason, unresolved []string) {
// Initialize slices // Initialize slices
resolved = make([]string, 0) resolved = make(map[string]InstallationReason)
unresolved = make([]string, 0) unresolved = make([]string, 0)
// Call unexported function // Call unexported function
resolvePackageDependenciesFromDatabase(&resolved, &unresolved, pkgInfo, checkMake, checkOptional, ignoreInstalled, verbose, rootDir) resolvePackageDependenciesFromDatabase(resolved, &unresolved, pkgInfo, InstallationReasonDependency, checkMake, checkOptional, ignoreInstalled, verbose, rootDir)
return resolved, unresolved return resolved, unresolved
} }
func resolvePackageDependenciesFromDatabase(resolved, unresolved *[]string, pkgInfo *PackageInfo, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) { func resolvePackageDependenciesFromDatabase(resolved map[string]InstallationReason, unresolved *[]string, pkgInfo *PackageInfo, installationReason InstallationReason, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) {
// Add current package name to unresolved slice // Add current package name to unresolved slice
*unresolved = append(*unresolved, pkgInfo.Name) *unresolved = append(*unresolved, pkgInfo.Name)
// Loop through all dependencies // Loop through all dependencies
for _, depend := range pkgInfo.GetDependencies(checkMake, checkOptional) { for depend, ir := range pkgInfo.GetDependencies(pkgInfo.Type == "source", checkOptional) {
if !slices.Contains(*resolved, depend) { if _, ok := resolved[depend]; !ok {
// Add current dependency to resolved slice when circular dependency is detected // Add current dependency to resolved slice when circular dependency is detected
if slices.Contains(*unresolved, depend) { if slices.Contains(*unresolved, depend) {
if verbose { if verbose {
fmt.Printf("Circular dependency was detected (%s -> %s). Installing %s first\n", pkgInfo.Name, depend, depend) fmt.Printf("Circular dependency was detected (%s -> %s). Installing %s first\n", pkgInfo.Name, depend, depend)
} }
if !slices.Contains(*resolved, depend) { if _, ok := resolved[depend]; !ok {
*resolved = append(*resolved, depend) resolved[depend] = ir
} }
continue continue
} else if ignoreInstalled && IsPackageProvided(depend, rootDir) { } else if ignoreInstalled && IsPackageProvided(depend, rootDir) {
@ -104,11 +112,12 @@ func resolvePackageDependenciesFromDatabase(resolved, unresolved *[]string, pkgI
continue continue
} }
} }
resolvePackageDependenciesFromDatabase(resolved, unresolved, entry.Info, checkMake, checkOptional, ignoreInstalled, verbose, rootDir) resolvePackageDependenciesFromDatabase(resolved, unresolved, entry.Info, ir, checkMake, checkOptional, ignoreInstalled, verbose, rootDir)
} }
} }
if !slices.Contains(*resolved, pkgInfo.Name) {
*resolved = append(*resolved, pkgInfo.Name) if _, ok := resolved[pkgInfo.Name]; !ok {
resolved[pkgInfo.Name] = installationReason
} }
*unresolved = stringSliceRemove(*unresolved, pkgInfo.Name) *unresolved = stringSliceRemove(*unresolved, pkgInfo.Name)
} }
@ -145,7 +154,7 @@ func GetPackageDependants(pkgName string, rootDir string) ([]string, error) {
dependencies := installedPkg.PkgInfo.GetDependencies(false, true) dependencies := installedPkg.PkgInfo.GetDependencies(false, true)
// Add installed package to list if its dependencies include pkgName // Add installed package to list if its dependencies include pkgName
if slices.Contains(dependencies, pkgName) { if _, ok := dependencies[pkgName]; ok {
ret = append(ret, installedPkgName) ret = append(ret, installedPkgName)
continue continue
} }
@ -153,7 +162,7 @@ func GetPackageDependants(pkgName string, rootDir string) ([]string, error) {
// Loop through each virtual package // Loop through each virtual package
for _, vpkg := range pkg.PkgInfo.Provides { for _, vpkg := range pkg.PkgInfo.Provides {
// Add installed package to list if its dependencies contain a provided virtual package // Add installed package to list if its dependencies contain a provided virtual package
if slices.Contains(dependencies, vpkg) { if _, ok := dependencies[vpkg]; ok {
ret = append(ret, installedPkgName) ret = append(ret, installedPkgName)
break break
} }

View File

@ -21,12 +21,11 @@ const (
func InstallPackages(rootDir string, installationReason InstallationReason, reinstallMethod ReinstallMethod, installOptionalDependencies, forceInstallation, verbose bool, packages ...string) (operation *BPMOperation, err error) { func InstallPackages(rootDir string, installationReason InstallationReason, reinstallMethod ReinstallMethod, installOptionalDependencies, forceInstallation, 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),
UnresolvedDepends: make([]string, 0), UnresolvedDepends: make([]string, 0),
Changes: make(map[string]string), Changes: make(map[string]string),
RootDir: rootDir, RootDir: rootDir,
ForceInstallationReason: installationReason, compiledPackages: make(map[string]string),
compiledPackages: make(map[string]string),
} }
// Resolve packages // Resolve packages
@ -46,7 +45,7 @@ func InstallPackages(rootDir string, installationReason InstallationReason, rein
operation.AppendAction(&InstallPackageAction{ operation.AppendAction(&InstallPackageAction{
File: pkg, File: pkg,
IsDependency: false, InstallationReason: installationReason,
BpmPackage: bpmpkg, BpmPackage: bpmpkg,
SplitPackageToInstall: splitPkg.Name, SplitPackageToInstall: splitPkg.Name,
}) })
@ -59,9 +58,9 @@ func InstallPackages(rootDir string, installationReason InstallationReason, rein
} }
operation.AppendAction(&InstallPackageAction{ operation.AppendAction(&InstallPackageAction{
File: pkg, File: pkg,
IsDependency: false, InstallationReason: installationReason,
BpmPackage: bpmpkg, BpmPackage: bpmpkg,
}) })
} else { } else {
var entry *BPMDatabaseEntry var entry *BPMDatabaseEntry
@ -85,8 +84,8 @@ func InstallPackages(rootDir string, installationReason InstallationReason, rein
} }
operation.AppendAction(&FetchPackageAction{ operation.AppendAction(&FetchPackageAction{
IsDependency: false, InstallationReason: installationReason,
DatabaseEntry: entry, DatabaseEntry: entry,
}) })
} }
} }
@ -161,7 +160,7 @@ func RemovePackages(rootDir string, removeUnusedPackagesOnly, cleanupDependencie
// Do package cleanup // Do package cleanup
if cleanupDependencies { if cleanupDependencies {
err := operation.Cleanup() err := operation.Cleanup(true)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not perform cleanup for operation: %s", err) return nil, fmt.Errorf("could not perform cleanup for operation: %s", err)
} }
@ -170,7 +169,7 @@ func RemovePackages(rootDir string, removeUnusedPackagesOnly, cleanupDependencie
} }
// CleanupPackages finds packages installed as dependencies which are no longer required by the rest of the system in the given root directory // CleanupPackages finds packages installed as dependencies which are no longer required by the rest of the system in the given root directory
func CleanupPackages(rootDir string) (operation *BPMOperation, err error) { func CleanupPackages(cleanupMakeDepends bool, rootDir string) (operation *BPMOperation, err error) {
operation = &BPMOperation{ operation = &BPMOperation{
Actions: make([]OperationAction, 0), Actions: make([]OperationAction, 0),
UnresolvedDepends: make([]string, 0), UnresolvedDepends: make([]string, 0),
@ -180,7 +179,7 @@ func CleanupPackages(rootDir string) (operation *BPMOperation, err error) {
} }
// Do package cleanup // Do package cleanup
err = operation.Cleanup() err = operation.Cleanup(cleanupMakeDepends)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not perform cleanup for operation: %s", err) return nil, fmt.Errorf("could not perform cleanup for operation: %s", err)
} }
@ -300,12 +299,11 @@ func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependenci
} }
operation = &BPMOperation{ operation = &BPMOperation{
Actions: make([]OperationAction, 0), Actions: make([]OperationAction, 0),
UnresolvedDepends: make([]string, 0), UnresolvedDepends: make([]string, 0),
Changes: make(map[string]string), Changes: make(map[string]string),
RootDir: rootDir, RootDir: rootDir,
ForceInstallationReason: InstallationReasonUnknown, compiledPackages: make(map[string]string),
compiledPackages: make(map[string]string),
} }
// Search for packages // Search for packages
@ -328,8 +326,8 @@ func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependenci
comparison := ComparePackageVersions(*entry.Info, *installedInfo) comparison := ComparePackageVersions(*entry.Info, *installedInfo)
if comparison > 0 { if comparison > 0 {
operation.AppendAction(&FetchPackageAction{ operation.AppendAction(&FetchPackageAction{
IsDependency: false, InstallationReason: GetInstallationReason(pkg, rootDir),
DatabaseEntry: entry, DatabaseEntry: entry,
}) })
} }
} }

View File

@ -11,12 +11,11 @@ import (
) )
type BPMOperation struct { type BPMOperation struct {
Actions []OperationAction Actions []OperationAction
UnresolvedDepends []string UnresolvedDepends []string
Changes map[string]string Changes map[string]string
RootDir string RootDir string
ForceInstallationReason InstallationReason compiledPackages map[string]string
compiledPackages map[string]string
} }
func (operation *BPMOperation) ActionsContainPackage(pkg string) bool { func (operation *BPMOperation) ActionsContainPackage(pkg string) bool {
@ -139,11 +138,11 @@ func (operation *BPMOperation) ResolveDependencies(reinstallDependencies, instal
continue continue
} }
resolved, unresolved := ResolvePackageDependenciesFromDatabases(pkgInfo, pkgInfo.Type == "source", installOptionalDependencies, !reinstallDependencies, verbose, operation.RootDir) resolved, unresolved := ResolveAllPackageDependenciesFromDatabases(pkgInfo, pkgInfo.Type == "source", installOptionalDependencies, !reinstallDependencies, verbose, operation.RootDir)
operation.UnresolvedDepends = append(operation.UnresolvedDepends, unresolved...) operation.UnresolvedDepends = append(operation.UnresolvedDepends, unresolved...)
for _, depend := range resolved { for depend, installationReason := range resolved {
if !operation.ActionsContainPackage(depend) && depend != pkgInfo.Name { if !operation.ActionsContainPackage(depend) && depend != pkgInfo.Name {
if !reinstallDependencies && IsPackageInstalled(depend, operation.RootDir) { if !reinstallDependencies && IsPackageInstalled(depend, operation.RootDir) {
continue continue
@ -153,8 +152,8 @@ func (operation *BPMOperation) ResolveDependencies(reinstallDependencies, instal
return errors.New("could not get database entry for package (" + depend + ")") return errors.New("could not get database entry for package (" + depend + ")")
} }
operation.InsertActionAt(pos, &FetchPackageAction{ operation.InsertActionAt(pos, &FetchPackageAction{
IsDependency: true, InstallationReason: installationReason,
DatabaseEntry: entry, DatabaseEntry: entry,
}) })
pos++ pos++
} }
@ -192,7 +191,7 @@ func (operation *BPMOperation) RemoveNeededPackages() error {
return nil return nil
} }
func (operation *BPMOperation) Cleanup() error { func (operation *BPMOperation) Cleanup(cleanupMakeDepends bool) error {
// Get all installed packages // Get all installed packages
installedPackageNames, err := GetInstalledPackages(operation.RootDir) installedPackageNames, err := GetInstalledPackages(operation.RootDir)
if err != nil { if err != nil {
@ -228,7 +227,7 @@ func (operation *BPMOperation) Cleanup() error {
} }
keepPackages = append(keepPackages, pkg.Name) keepPackages = append(keepPackages, pkg.Name)
resolved := pkg.GetAllDependencies(false, true, operation.RootDir) resolved := pkg.GetAllDependencies(!cleanupMakeDepends, true, operation.RootDir)
for _, value := range resolved { for _, value := range resolved {
if !slices.Contains(keepPackages, value) { if !slices.Contains(keepPackages, value) {
keepPackages = append(keepPackages, value) keepPackages = append(keepPackages, value)
@ -336,12 +335,15 @@ func (operation *BPMOperation) ShowOperationSummary() {
for _, value := range operation.Actions { for _, value := range operation.Actions {
var pkgInfo *PackageInfo var pkgInfo *PackageInfo
var installationReason = InstallationReasonUnknown
if value.GetActionType() == "install" { if value.GetActionType() == "install" {
installationReason = value.(*InstallPackageAction).InstallationReason
pkgInfo = value.(*InstallPackageAction).BpmPackage.PkgInfo pkgInfo = value.(*InstallPackageAction).BpmPackage.PkgInfo
if value.(*InstallPackageAction).SplitPackageToInstall != "" { if value.(*InstallPackageAction).SplitPackageToInstall != "" {
pkgInfo = pkgInfo.GetSplitPackageInfo(value.(*InstallPackageAction).SplitPackageToInstall) pkgInfo = pkgInfo.GetSplitPackageInfo(value.(*InstallPackageAction).SplitPackageToInstall)
} }
} else if value.GetActionType() == "fetch" { } else if value.GetActionType() == "fetch" {
installationReason = value.(*FetchPackageAction).InstallationReason
pkgInfo = value.(*FetchPackageAction).DatabaseEntry.Info pkgInfo = value.(*FetchPackageAction).DatabaseEntry.Info
} else { } else {
pkgInfo = value.(*RemovePackageAction).BpmPackage.PkgInfo pkgInfo = value.(*RemovePackageAction).BpmPackage.PkgInfo
@ -350,21 +352,32 @@ func (operation *BPMOperation) ShowOperationSummary() {
} }
installedInfo := GetPackageInfo(pkgInfo.Name, operation.RootDir) installedInfo := GetPackageInfo(pkgInfo.Name, operation.RootDir)
sourceInfo := "" additionalInfo := ""
switch installationReason {
case InstallationReasonManual:
additionalInfo = "(Manual)"
case InstallationReasonDependency:
additionalInfo = "(Dependency)"
case InstallationReasonMakeDependency:
additionalInfo = "(Make dependency)"
default:
additionalInfo = "(Unknown)"
}
if pkgInfo.Type == "source" { if pkgInfo.Type == "source" {
sourceInfo = "(From Source)" additionalInfo += " (From Source)"
} }
if installedInfo == nil { if installedInfo == nil {
fmt.Printf("%s: %s (Install) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo) fmt.Printf("%s: %s (Install) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), additionalInfo)
} else { } else {
comparison := ComparePackageVersions(*pkgInfo, *installedInfo) comparison := ComparePackageVersions(*pkgInfo, *installedInfo)
if comparison < 0 { if comparison < 0 {
fmt.Printf("%s: %s -> %s (Downgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo) fmt.Printf("%s: %s -> %s (Downgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), additionalInfo)
} else if comparison > 0 { } else if comparison > 0 {
fmt.Printf("%s: %s -> %s (Upgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo) fmt.Printf("%s: %s -> %s (Upgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), additionalInfo)
} else { } else {
fmt.Printf("%s: %s (Reinstall) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo) fmt.Printf("%s: %s (Reinstall) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), additionalInfo)
} }
} }
} }
@ -465,15 +478,15 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
if bpmpkg.PkgInfo.IsSplitPackage() { if bpmpkg.PkgInfo.IsSplitPackage() {
operation.Actions[i] = &InstallPackageAction{ operation.Actions[i] = &InstallPackageAction{
File: fetchedPackages[entry.Download], File: fetchedPackages[entry.Download],
IsDependency: action.(*FetchPackageAction).IsDependency, InstallationReason: action.(*FetchPackageAction).InstallationReason,
BpmPackage: bpmpkg, BpmPackage: bpmpkg,
SplitPackageToInstall: entry.Info.Name, SplitPackageToInstall: entry.Info.Name,
} }
} else { } else {
operation.Actions[i] = &InstallPackageAction{ operation.Actions[i] = &InstallPackageAction{
File: fetchedPackages[entry.Download], File: fetchedPackages[entry.Download],
IsDependency: action.(*FetchPackageAction).IsDependency, InstallationReason: action.(*FetchPackageAction).InstallationReason,
BpmPackage: bpmpkg, BpmPackage: bpmpkg,
} }
} }
} }
@ -553,7 +566,7 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
} }
} }
if value.IsDependency { if value.InstallationReason != InstallationReasonManual {
err = installPackage(fileToInstall, operation.RootDir, verbose, true) err = installPackage(fileToInstall, operation.RootDir, verbose, true)
} else { } else {
err = installPackage(fileToInstall, operation.RootDir, verbose, force) err = installPackage(fileToInstall, operation.RootDir, verbose, force)
@ -561,13 +574,8 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
if err != nil { if err != nil {
return errors.New(fmt.Sprintf("could not install package (%s): %s\n", bpmpkg.PkgInfo.Name, err)) return errors.New(fmt.Sprintf("could not install package (%s): %s\n", bpmpkg.PkgInfo.Name, err))
} }
if operation.ForceInstallationReason != InstallationReasonUnknown && !value.IsDependency { if !isReinstall {
err := SetInstallationReason(bpmpkg.PkgInfo.Name, operation.ForceInstallationReason, operation.RootDir) err := SetInstallationReason(bpmpkg.PkgInfo.Name, value.InstallationReason, operation.RootDir)
if err != nil {
return errors.New(fmt.Sprintf("could not set installation reason for package (%s): %s\n", value.BpmPackage.PkgInfo.Name, err))
}
} else if value.IsDependency && !isReinstall {
err := SetInstallationReason(bpmpkg.PkgInfo.Name, InstallationReasonDependency, operation.RootDir)
if err != nil { if err != nil {
return errors.New(fmt.Sprintf("could not set installation reason for package (%s): %s\n", value.BpmPackage.PkgInfo.Name, err)) return errors.New(fmt.Sprintf("could not set installation reason for package (%s): %s\n", value.BpmPackage.PkgInfo.Name, err))
} }
@ -586,7 +594,7 @@ type OperationAction interface {
type InstallPackageAction struct { type InstallPackageAction struct {
File string File string
IsDependency bool InstallationReason InstallationReason
SplitPackageToInstall string SplitPackageToInstall string
BpmPackage *BPMPackage BpmPackage *BPMPackage
} }
@ -596,8 +604,8 @@ func (action *InstallPackageAction) GetActionType() string {
} }
type FetchPackageAction struct { type FetchPackageAction struct {
IsDependency bool InstallationReason InstallationReason
DatabaseEntry *BPMDatabaseEntry DatabaseEntry *BPMDatabaseEntry
} }
func (action *FetchPackageAction) GetActionType() string { func (action *FetchPackageAction) GetActionType() string {

View File

@ -92,9 +92,10 @@ func (pkgInfo *PackageInfo) GetSplitPackageInfo(splitPkg string) *PackageInfo {
type InstallationReason string type InstallationReason string
const ( const (
InstallationReasonManual InstallationReason = "manual" InstallationReasonManual InstallationReason = "manual"
InstallationReasonDependency InstallationReason = "dependency" InstallationReasonDependency InstallationReason = "dependency"
InstallationReasonUnknown InstallationReason = "unknown" InstallationReasonMakeDependency InstallationReason = "make_dependency"
InstallationReasonUnknown InstallationReason = "unknown"
) )
func ComparePackageVersions(info1, info2 PackageInfo) int { func ComparePackageVersions(info1, info2 PackageInfo) int {
@ -119,6 +120,8 @@ func GetInstallationReason(pkg, rootDir string) InstallationReason {
return InstallationReasonManual return InstallationReasonManual
} else if reason == "dependency" { } else if reason == "dependency" {
return InstallationReasonDependency return InstallationReasonDependency
} else if reason == "make_dependency" {
return InstallationReasonMakeDependency
} }
return InstallationReasonUnknown return InstallationReasonUnknown
} }
@ -524,7 +527,19 @@ func CreateReadableInfo(showArchitecture, showType, showPackageRelations, showIn
appendArray("Split Packages", splitPkgs) appendArray("Split Packages", splitPkgs)
} }
if IsPackageInstalled(pkgInfo.Name, rootDir) && showInstallationReason { if IsPackageInstalled(pkgInfo.Name, rootDir) && showInstallationReason {
ret = append(ret, "Installation Reason: "+string(GetInstallationReason(pkgInfo.Name, rootDir))) installationReason := GetInstallationReason(pkgInfo.Name, rootDir)
var installationReasonString string
switch installationReason {
case InstallationReasonManual:
installationReasonString = "Manual"
case InstallationReasonDependency:
installationReasonString = "Dependency"
case InstallationReasonMakeDependency:
installationReasonString = "Make dependency"
default:
installationReasonString = "Unknown"
}
ret = append(ret, "Installation Reason: "+installationReasonString)
} }
return strings.Join(ret, "\n") return strings.Join(ret, "\n")
} }