11 Commits
13 changed files with 158 additions and 152 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ ROOT_COMPILATION_GID ?= 65534
build: build:
mkdir -p build mkdir -p build
cd src/bpm; $(GO) build $(GOFLAGS) -ldflags "-w -X 'git.enumerated.dev/bubble-package-manager/bpm/src/bpm/config.BpmVersion=$(VERSION)' -X 'git.enumerated.dev/bubble-package-manager/bpm/src/bpmlib.rootCompilationUID=$(ROOT_COMPILATION_UID)' -X 'git.enumerated.dev/bubble-package-manager/bpm/src/bpmlib.rootCompilationGID=$(ROOT_COMPILATION_GID)'" -o ../../build/bpm git.enumerated.dev/bubble-package-manager/bpm/src/bpm cd src/bpm; $(GO) build $(GOFLAGS) -ldflags "-w -X 'main.BpmVersion=$(VERSION)' -X 'github.com/EnumeratedDev/bpm/src/bpmlib.rootCompilationUID=$(ROOT_COMPILATION_UID)' -X 'github.com/EnumeratedDev/bpm/src/bpmlib.rootCompilationGID=$(ROOT_COMPILATION_GID)'" -o ../../build/bpm bpm
install: build/bpm config/ install: build/bpm config/
# Create directory # Create directory
-3
View File
@@ -1,3 +0,0 @@
package config
var BpmVersion = "dev"
+3 -3
View File
@@ -1,14 +1,14 @@
module git.enumerated.dev/bubble-package-manager/bpm/src/bpm module bpm
go 1.24.0 go 1.24.0
require ( require (
git.enumerated.dev/bubble-package-manager/bpm/src/bpmlib v0.5.0 github.com/EnumeratedDev/bpm/src/bpmlib v0.0.0
github.com/lithammer/fuzzysearch v1.1.8 github.com/lithammer/fuzzysearch v1.1.8
github.com/spf13/pflag v1.0.10 github.com/spf13/pflag v1.0.10
) )
replace git.enumerated.dev/bubble-package-manager/bpm/src/bpmlib => ../bpmlib replace github.com/EnumeratedDev/bpm/src/bpmlib => ../bpmlib
require ( require (
github.com/drone/envsubst v1.0.3 // indirect github.com/drone/envsubst v1.0.3 // indirect
+62 -21
View File
@@ -14,8 +14,7 @@ import (
"sort" "sort"
"strings" "strings"
"git.enumerated.dev/bubble-package-manager/bpm/src/bpm/config" "github.com/EnumeratedDev/bpm/src/bpmlib"
"git.enumerated.dev/bubble-package-manager/bpm/src/bpmlib"
"github.com/lithammer/fuzzysearch/fuzzy" "github.com/lithammer/fuzzysearch/fuzzy"
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
@@ -26,6 +25,8 @@ import (
/* A simple-to-use package manager */ /* A simple-to-use package manager */
/* ------------------------------------------------------- */ /* ------------------------------------------------------- */
var BpmVersion = "dev"
var currentFlagSet *flag.FlagSet var currentFlagSet *flag.FlagSet
var exitCode = 0 var exitCode = 0
@@ -47,7 +48,7 @@ func main() {
switch subcommand { switch subcommand {
case "v", "version": case "v", "version":
fmt.Println("Bubble Package Manager (BPM)") fmt.Println("Bubble Package Manager (BPM)")
fmt.Println("Version: " + config.BpmVersion) fmt.Println("Version: " + BpmVersion)
case "q", "query": case "q", "query":
// Setup flags and help // Setup flags and help
currentFlagSet = flag.NewFlagSet("query", flag.ExitOnError) currentFlagSet = flag.NewFlagSet("query", flag.ExitOnError)
@@ -137,6 +138,7 @@ func main() {
currentFlagSet.BoolP("force", "f", false, "Bypass warnings during package update") currentFlagSet.BoolP("force", "f", false, "Bypass warnings during package update")
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.BoolP("optional", "o", false, "Install all optional dependencies") currentFlagSet.BoolP("optional", "o", false, "Install all optional dependencies")
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:])
@@ -254,7 +256,14 @@ func showPackageInfo() {
} }
fmt.Println("File: " + abs) fmt.Println("File: " + abs)
} }
fmt.Println(bpmpkg.CreateReadableInfo(rootDir, showHumanReadableSize)) fmt.Println(bpmpkg.PkgInfo.CreateReadableInfo(rootDir))
if bpmpkg.PkgInfo.Type == "binary" {
if !showHumanReadableSize {
fmt.Printf("Installed size: %d\n", bpmpkg.GetInstalledSize())
} else {
fmt.Printf("Installed size: %s\n", bpmlib.BytesToHumanReadable(bpmpkg.GetInstalledSize()))
}
}
} }
} }
@@ -292,9 +301,21 @@ func showPackageList() {
return return
} }
installedPackages := make([]*bpmlib.BPMPackage, len(installedPackageNames)) installedPackages := make([]struct {
pkgInfo bpmlib.PackageInfo
installedSize int64
}, len(installedPackageNames))
for i, pkgName := range installedPackageNames { for i, pkgName := range installedPackageNames {
installedPackages[i] = bpmlib.GetPackage(pkgName, rootDir) pkgInfo := *bpmlib.GetPackageInfo(pkgName, rootDir)
installedSize := bpmlib.GetPackage(pkgName, rootDir).GetInstalledSize()
installedPackages[i] = struct {
pkgInfo bpmlib.PackageInfo
installedSize int64
}{
pkgInfo: pkgInfo,
installedSize: installedSize,
}
} }
databaseEntries := make([]*bpmlib.BPMDatabaseEntry, 0) databaseEntries := make([]*bpmlib.BPMDatabaseEntry, 0)
@@ -305,8 +326,11 @@ func showPackageList() {
switch sortPackages { switch sortPackages {
case "", "name": case "", "name":
case "size": case "size":
slices.SortFunc(installedPackages, func(a, b *bpmlib.BPMPackage) int { slices.SortFunc(installedPackages, func(a, b struct {
return int(b.GetInstalledSize() - a.GetInstalledSize()) pkgInfo bpmlib.PackageInfo
installedSize int64
}) int {
return int(b.installedSize - a.installedSize)
}) })
slices.SortFunc(databaseEntries, func(a, b *bpmlib.BPMDatabaseEntry) int { slices.SortFunc(databaseEntries, func(a, b *bpmlib.BPMDatabaseEntry) int {
return int(b.InstalledSize - a.InstalledSize) return int(b.InstalledSize - a.InstalledSize)
@@ -335,7 +359,7 @@ func showPackageList() {
} }
} else { } else {
for _, pkg := range installedPackages { for _, pkg := range installedPackages {
installationReason := bpmlib.GetInstallationReason(pkg.PkgInfo.Name, rootDir) installationReason := bpmlib.GetInstallationReason(pkg.pkgInfo.Name, rootDir)
if installationReason == bpmlib.InstallationReasonManual && !showManual { if installationReason == bpmlib.InstallationReasonManual && !showManual {
continue continue
} else if installationReason == bpmlib.InstallationReasonDependency && !showDepends { } else if installationReason == bpmlib.InstallationReasonDependency && !showDepends {
@@ -346,7 +370,7 @@ func showPackageList() {
continue continue
} }
fmt.Println(pkg.PkgInfo.Name) fmt.Println(pkg.pkgInfo.Name)
} }
} }
} else { } else {
@@ -366,13 +390,8 @@ func showPackageList() {
fmt.Println("No packages have been installed") fmt.Println("No packages have been installed")
return return
} }
for n, bpmpkg := range installedPackages { for n, pkg := range installedPackages {
if bpmpkg == nil { installationReason := bpmlib.GetInstallationReason(pkg.pkgInfo.Name, rootDir)
fmt.Printf("Package (%s) could not be found\n", installedPackageNames[n])
continue
}
installationReason := bpmlib.GetInstallationReason(bpmpkg.PkgInfo.Name, rootDir)
if installationReason == bpmlib.InstallationReasonManual && !showManual { if installationReason == bpmlib.InstallationReasonManual && !showManual {
continue continue
} else if installationReason == bpmlib.InstallationReasonDependency && !showDepends { } else if installationReason == bpmlib.InstallationReasonDependency && !showDepends {
@@ -386,7 +405,15 @@ func showPackageList() {
if n != 0 { if n != 0 {
fmt.Println() fmt.Println()
} }
fmt.Println(bpmpkg.CreateReadableInfo(rootDir, showHumanReadableSize))
fmt.Println(pkg.pkgInfo.CreateReadableInfo(rootDir))
if pkg.pkgInfo.Type == "binary" {
if !showHumanReadableSize {
fmt.Printf("Installed size: %d\n", pkg.installedSize)
} else {
fmt.Printf("Installed size: %s\n", bpmlib.BytesToHumanReadable(pkg.installedSize))
}
}
} }
} }
} }
@@ -600,7 +627,7 @@ func installPackages() {
// Show optional dependencies // Show optional dependencies
if !installOptional && len(optionalDepends) != 0 { if !installOptional && len(optionalDepends) != 0 {
// List optional dependencies // List optional dependencies
fmt.Println("The following opitonal dependenices have been discovered:") fmt.Println("The following optional dependenices have been discovered:")
for dependant, depends := range optionalDepends { for dependant, depends := range optionalDepends {
fmt.Printf("%s: \n", dependant) fmt.Printf("%s: \n", dependant)
for _, depend := range depends { for _, depend := range depends {
@@ -869,6 +896,7 @@ func updatePackages() {
force, _ := currentFlagSet.GetBool("force") force, _ := currentFlagSet.GetBool("force")
yesAll, _ := currentFlagSet.GetBool("yes") yesAll, _ := currentFlagSet.GetBool("yes")
noSync, _ := currentFlagSet.GetBool("no-sync") noSync, _ := currentFlagSet.GetBool("no-sync")
allowDowngrades, _ := currentFlagSet.GetBool("allow-downgrades")
installOptional, _ := currentFlagSet.GetBool("optional") installOptional, _ := currentFlagSet.GetBool("optional")
// Check for required permissions // Check for required permissions
@@ -897,14 +925,25 @@ func updatePackages() {
} }
} }
// Confirmation Prompt
if !noSync && !yesAll {
if !showConfirmationPrompt("Do you wish to sync all databases?", false) {
fmt.Println("Cancelling package update...")
exitCode = 1
return
}
}
// Create update operation // Create update operation
operation, err := bpmlib.UpdatePackages(rootDir, !noSync, installOptional, force, verbose) operation, err := bpmlib.UpdatePackages(rootDir, !noSync, allowDowngrades, installOptional, force, 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
return return
} else if err != nil { } else if err != nil {
log.Printf("Error: could not setup operation: %s\n", err) log.Printf("Error: could not setup operation: %s\n", err)
exitCode = 1
return
} }
// Exit if operation contains no actions // Exit if operation contains no actions
@@ -980,7 +1019,7 @@ func updatePackages() {
// Show optional dependencies // Show optional dependencies
if !installOptional && len(optionalDepends) != 0 { if !installOptional && len(optionalDepends) != 0 {
// List optional dependencies // List optional dependencies
fmt.Println("The following opitonal dependenices have been discovered:") fmt.Println("The following optional dependenices have been discovered:")
for dependant, depends := range optionalDepends { for dependant, depends := range optionalDepends {
fmt.Printf("%s: \n", dependant) fmt.Printf("%s: \n", dependant)
for _, depend := range depends { for _, depend := range depends {
@@ -1064,6 +1103,8 @@ func getFileOwner() {
// Print packages // Print packages
if len(pkgList) == 0 { if len(pkgList) == 0 {
fmt.Printf("%s (%s) is not owned by any packages!\n", absPath, pathType) fmt.Printf("%s (%s) is not owned by any packages!\n", absPath, pathType)
exitCode = 1
return
} else { } else {
fmt.Printf("%s (%s) is owned by the following packages:\n", absPath, pathType) fmt.Printf("%s (%s) is owned by the following packages:\n", absPath, pathType)
for _, pkg := range pkgList { for _, pkg := range pkgList {
+9 -4
View File
@@ -137,6 +137,7 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks, k
env = append(env, "BPM_PKG_NAME="+bpmpkg.PkgInfo.Name) env = append(env, "BPM_PKG_NAME="+bpmpkg.PkgInfo.Name)
env = append(env, "BPM_PKG_VERSION="+bpmpkg.PkgInfo.Version) env = append(env, "BPM_PKG_VERSION="+bpmpkg.PkgInfo.Version)
env = append(env, "BPM_PKG_REVISION="+strconv.Itoa(bpmpkg.PkgInfo.Revision)) env = append(env, "BPM_PKG_REVISION="+strconv.Itoa(bpmpkg.PkgInfo.Revision))
env = append(env, "BPM_PKG_URL="+bpmpkg.PkgInfo.Url)
env = append(env, "BPM_PKG_ARCH="+bpmpkg.PkgInfo.OutputArch) env = append(env, "BPM_PKG_ARCH="+bpmpkg.PkgInfo.OutputArch)
env = append(env, CompilationBPMConfig.CompilationEnvironment...) env = append(env, CompilationBPMConfig.CompilationEnvironment...)
@@ -434,10 +435,12 @@ func downloadPackageFiles(pkgInfo *PackageInfo, tempDirectory string, verbose bo
// Replace variables // Replace variables
replaceVars := func(s string) string { replaceVars := func(s string) string {
switch s { switch s {
case "BPM_PKG_VERSION":
return pkgInfo.Version
case "BPM_PKG_NAME": case "BPM_PKG_NAME":
return pkgInfo.Name return pkgInfo.Name
case "BPM_PKG_VERSION":
return pkgInfo.Version
case "BPM_PKG_URL":
return pkgInfo.Url
case "BPM_SOURCE": case "BPM_SOURCE":
return path.Join(tempDirectory, "source/") return path.Join(tempDirectory, "source/")
default: default:
@@ -557,10 +560,12 @@ func downloadPackageFiles(pkgInfo *PackageInfo, tempDirectory string, verbose bo
gitBranch := download.GitBranch gitBranch := download.GitBranch
gitBranch, err := envsubst.Eval(gitBranch, func(s string) string { gitBranch, err := envsubst.Eval(gitBranch, func(s string) string {
switch s { switch s {
case "BPM_PKG_VERSION":
return pkgInfo.Version
case "BPM_PKG_NAME": case "BPM_PKG_NAME":
return pkgInfo.Name return pkgInfo.Name
case "BPM_PKG_VERSION":
return pkgInfo.Version
case "BPM_PKG_URL":
return pkgInfo.Url
default: default:
return "" return ""
} }
+3 -10
View File
@@ -63,11 +63,12 @@ func (db *configDatabase) ReadLocalDatabase() error {
database.Name = db.Name database.Name = db.Name
database.Source = db.Source database.Source = db.Source
entriesToRemove := make([]string, 0)
for entryName, entry := range database.Entries { for entryName, entry := range database.Entries {
entry.Database = database entry.Database = database
if entry.Info.IsSplitPackage() { if entry.Info.IsSplitPackage() {
delete(database.Entries, entryName)
// Handle split packages // Handle split packages
for _, splitPkg := range entry.Info.SplitPackages { for _, splitPkg := range entry.Info.SplitPackages {
// Turn split package into json data // Turn split package into json data
@@ -106,9 +107,6 @@ func (db *configDatabase) ReadLocalDatabase() error {
for _, p := range splitPkg.Provides { for _, p := range splitPkg.Provides {
database.VirtualPackages[p] = append(database.VirtualPackages[p], splitPkg.Name) database.VirtualPackages[p] = append(database.VirtualPackages[p], splitPkg.Name)
} }
// Add current entry to list for removal
entriesToRemove = append(entriesToRemove, entryName)
} }
} else { } else {
// Add virtual packages to database // Add virtual packages to database
@@ -118,11 +116,6 @@ func (db *configDatabase) ReadLocalDatabase() error {
} }
} }
// Remove entries
for _, entryName := range entriesToRemove {
delete(database.Entries, entryName)
}
BPMDatabases[db.Name] = database BPMDatabases[db.Name] = database
return nil return nil
@@ -403,7 +396,7 @@ func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string, humanReadableS
installedSize := entry.InstalledSize installedSize := entry.InstalledSize
var installedSizeStr string var installedSizeStr string
if humanReadableSize { if humanReadableSize {
installedSizeStr = bytesToHumanReadable(installedSize) installedSizeStr = BytesToHumanReadable(installedSize)
} else { } else {
installedSizeStr = strconv.FormatInt(installedSize, 10) installedSizeStr = strconv.FormatInt(installedSize, 10)
} }
+16 -28
View File
@@ -177,39 +177,33 @@ func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, u
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, err := GetInstalledPackages(rootDir) pkgs, ok := localPackageInformation[rootDir]
if err != nil { if !ok {
return nil return nil
} }
// Loop through all installed packages // Loop through all installed packages
for _, installedPkgName := range pkgs { for _, installedPkg := range pkgs {
// Get installed BPM package
installedPkg := GetPackage(installedPkgName, rootDir)
if installedPkg == nil {
return nil
}
// Skip iteration if comparing the same packages // Skip iteration if comparing the same packages
if installedPkg.PkgInfo.Name == pkgInfo.Name { if installedPkg.Name == pkgInfo.Name {
continue continue
} }
// Add installed package to list if its dependencies include pkgName // Add installed package to list if its dependencies include pkgName
if slices.ContainsFunc(installedPkg.PkgInfo.Depends, func(n string) bool { if slices.ContainsFunc(installedPkg.Depends, func(n string) bool {
return n == pkgInfo.Name return n == pkgInfo.Name
}) { }) {
dependants = append(dependants, installedPkgName) dependants = append(dependants, installedPkg.Name)
continue continue
} }
// Loop through each virtual package // Loop through each virtual package
for _, vpkg := range pkgInfo.Provides { for _, vpkg := range 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.ContainsFunc(installedPkg.PkgInfo.Depends, func(n string) bool { if slices.ContainsFunc(installedPkg.Depends, func(n string) bool {
return n == vpkg return n == vpkg
}) { }) {
dependants = append(dependants, installedPkgName) dependants = append(dependants, installedPkg.Name)
break break
} }
} }
@@ -220,39 +214,33 @@ func (pkgInfo *PackageInfo) GetPackageDependants(rootDir string) (dependants []s
func (pkgInfo *PackageInfo) GetPackageOptionalDependants(rootDir string) (dependants []string) { func (pkgInfo *PackageInfo) GetPackageOptionalDependants(rootDir string) (dependants []string) {
// Get installed package names // Get installed package names
pkgs, err := GetInstalledPackages(rootDir) pkgs, ok := localPackageInformation[rootDir]
if err != nil { if !ok {
return nil return nil
} }
// Loop through all installed packages // Loop through all installed packages
for _, installedPkgName := range pkgs { for _, installedPkg := range pkgs {
// Get installed BPM package
installedPkg := GetPackage(installedPkgName, rootDir)
if installedPkg == nil {
return nil
}
// Skip iteration if comparing the same packages // Skip iteration if comparing the same packages
if installedPkg.PkgInfo.Name == pkgInfo.Name { if installedPkg.Name == pkgInfo.Name {
continue continue
} }
// Add installed package to list if its optional dependencies include pkgName // Add installed package to list if its optional dependencies include pkgName
if slices.ContainsFunc(installedPkg.PkgInfo.OptionalDepends, func(n string) bool { if slices.ContainsFunc(installedPkg.OptionalDepends, func(n string) bool {
return n == pkgInfo.Name return n == pkgInfo.Name
}) { }) {
dependants = append(dependants, installedPkgName) dependants = append(dependants, installedPkg.Name)
continue continue
} }
// Loop through each virtual package // Loop through each virtual package
for _, vpkg := range pkgInfo.Provides { for _, vpkg := range pkgInfo.Provides {
// Add installed package to list if its optional dependencies contain a provided virtual package // Add installed package to list if its optional dependencies contain a provided virtual package
if slices.ContainsFunc(installedPkg.PkgInfo.OptionalDepends, func(n string) bool { if slices.ContainsFunc(installedPkg.OptionalDepends, func(n string) bool {
return n == vpkg return n == vpkg
}) { }) {
dependants = append(dependants, installedPkgName) dependants = append(dependants, installedPkg.Name)
break break
} }
} }
+2 -2
View File
@@ -365,7 +365,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, installOptionalDependencies, forceInstallation, verbose bool) (operation *BPMOperation, err error) { func UpdatePackages(rootDir string, syncDatabase bool, allowDowngrades bool, installOptionalDependencies, forceInstallation, verbose bool) (operation *BPMOperation, err error) {
// Sync databases // Sync databases
if syncDatabase { if syncDatabase {
err := SyncDatabase(verbose) err := SyncDatabase(verbose)
@@ -419,7 +419,7 @@ func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependenci
return nil, fmt.Errorf("could not get package info for package (%s)", pkg) return nil, fmt.Errorf("could not get package info for package (%s)", pkg)
} else { } else {
comparison := CompareVersions(entry.Info.GetFullVersion(), installedInfo.GetFullVersion()) comparison := CompareVersions(entry.Info.GetFullVersion(), installedInfo.GetFullVersion())
if comparison > 0 { if (!allowDowngrades && comparison > 0) || (allowDowngrades && comparison != 0) {
operation.AppendAction(&FetchPackageAction{ operation.AppendAction(&FetchPackageAction{
InstallationReason: GetInstallationReason(pkg, rootDir), InstallationReason: GetInstallationReason(pkg, rootDir),
DatabaseEntry: entry, DatabaseEntry: entry,
+1 -1
View File
@@ -1,4 +1,4 @@
module git.enumerated.dev/bubble-package-manager/bpm/src/bpmlib module github.com/EnumeratedDev/bpm/src/bpmlib
go 1.24.0 go 1.24.0
+21 -27
View File
@@ -9,7 +9,7 @@ import (
"strings" "strings"
) )
var localPackageInformation map[string]map[string]*BPMPackage = make(map[string]map[string]*BPMPackage) var localPackageInformation map[string]map[string]*PackageInfo = make(map[string]map[string]*PackageInfo)
func initializeLocalPackageInformation(rootDir string) (err error) { func initializeLocalPackageInformation(rootDir string) (err error) {
// Return if information is already initialized // Return if information is already initialized
@@ -17,7 +17,7 @@ func initializeLocalPackageInformation(rootDir string) (err error) {
return nil return nil
} }
tempPackageInformation := make(map[string]*BPMPackage) tempPackageInformation := make(map[string]*PackageInfo)
// Get path to installed package information directory // Get path to installed package information directory
installedDir := path.Join(rootDir, "var/lib/bpm/installed/") installedDir := path.Join(rootDir, "var/lib/bpm/installed/")
@@ -25,7 +25,7 @@ func initializeLocalPackageInformation(rootDir string) (err error) {
// Get directory content // Get directory content
items, err := os.ReadDir(installedDir) items, err := os.ReadDir(installedDir)
if os.IsNotExist(err) { if os.IsNotExist(err) {
localPackageInformation[rootDir] = make(map[string]*BPMPackage) localPackageInformation[rootDir] = make(map[string]*PackageInfo)
return nil return nil
} }
if err != nil { if err != nil {
@@ -49,14 +49,8 @@ func initializeLocalPackageInformation(rootDir string) (err error) {
return err return err
} }
// Read package files
files := getPackageFiles(info.Name, rootDir)
// Add package to slice // Add package to slice
tempPackageInformation[info.Name] = &BPMPackage{ tempPackageInformation[info.Name] = info
PkgInfo: info,
PkgFiles: files,
}
} }
localPackageInformation[rootDir] = tempPackageInformation localPackageInformation[rootDir] = tempPackageInformation
@@ -71,8 +65,8 @@ func GetInstalledPackages(rootDir string) (ret []string, err error) {
} }
// Loop through each package and add it to slice // Loop through each package and add it to slice
for _, bpmpkg := range localPackageInformation[rootDir] { for _, pkgInfo := range localPackageInformation[rootDir] {
ret = append(ret, bpmpkg.PkgInfo.Name) ret = append(ret, pkgInfo.Name)
} }
// Sort packages // Sort packages
@@ -94,18 +88,6 @@ func IsPackageInstalled(pkg, rootDir string) bool {
return true return true
} }
func GetPackageInfo(pkg string, rootDir string) *PackageInfo {
// Get BPM package
bpmpkg := GetPackage(pkg, rootDir)
// Return nil if not found
if bpmpkg == nil {
return nil
}
return bpmpkg.PkgInfo
}
func IsVirtualPackage(pkg, rootDir string) (bool, string) { func IsVirtualPackage(pkg, rootDir string) (bool, string) {
pkgs, err := GetInstalledPackages(rootDir) pkgs, err := GetInstalledPackages(rootDir)
if err != nil { if err != nil {
@@ -146,15 +128,27 @@ func IsPackageProvided(pkg, rootDir string) bool {
return false return false
} }
func GetPackage(pkg, rootDir string) *BPMPackage { func GetPackageInfo(pkg string, rootDir string) *PackageInfo {
err := initializeLocalPackageInformation(rootDir) err := initializeLocalPackageInformation(rootDir)
if err != nil { if err != nil {
return nil return nil
} }
bpmpkg := localPackageInformation[rootDir][pkg] return localPackageInformation[rootDir][pkg]
}
return bpmpkg func GetPackage(pkg, rootDir string) *BPMPackage {
pkgInfo := GetPackageInfo(pkg, rootDir)
if pkgInfo == nil {
return nil
}
files := getPackageFiles(pkgInfo.Name, rootDir)
return &BPMPackage{
PkgInfo: pkgInfo,
PkgFiles: files,
}
} }
func GetAllPackageFiles(rootDir string, excludePackages ...string) (map[string][]*BPMPackage, error) { func GetAllPackageFiles(rootDir string, excludePackages ...string) (map[string][]*BPMPackage, error) {
+11 -11
View File
@@ -310,29 +310,29 @@ func (operation *BPMOperation) CheckForConflicts() map[string][]string {
// Check for conflicts with installed packages // Check for conflicts with installed packages
for _, installedPkg := range installedPackages { for _, installedPkg := range installedPackages {
// Skip if package is to be removed // Skip if package is to be removed
if slices.Contains(removedPackages, installedPkg.PkgInfo.Name) { if slices.Contains(removedPackages, installedPkg.Name) {
continue continue
} }
// Skip if same package // Skip if same package
if pkgInfo.Name == installedPkg.PkgInfo.Name { if pkgInfo.Name == installedPkg.Name {
continue continue
} }
// Check for new package conflicts // Check for new package conflicts
if slices.Contains(pkgInfo.Conflicts, installedPkg.PkgInfo.Name) { if slices.Contains(pkgInfo.Conflicts, installedPkg.Name) {
conflicts[pkgInfo.Name] = append(conflicts[pkgInfo.Name], installedPkg.PkgInfo.Name) conflicts[pkgInfo.Name] = append(conflicts[pkgInfo.Name], installedPkg.Name)
} }
for _, vpkg := range installedPkg.PkgInfo.Provides { for _, vpkg := range installedPkg.Provides {
if slices.Contains(pkgInfo.Conflicts, vpkg) { if slices.Contains(pkgInfo.Conflicts, vpkg) {
conflicts[pkgInfo.Name] = append(conflicts[pkgInfo.Name], vpkg+" ("+installedPkg.PkgInfo.Name+")") conflicts[pkgInfo.Name] = append(conflicts[pkgInfo.Name], vpkg+" ("+installedPkg.Name+")")
} }
} }
// Check for installed package conflicts // Check for installed package conflicts
for _, vpkg := range pkgInfo.Provides { for _, vpkg := range pkgInfo.Provides {
if slices.Contains(installedPkg.PkgInfo.Conflicts, vpkg) { if slices.Contains(installedPkg.Conflicts, vpkg) {
conflicts[installedPkg.PkgInfo.Name] = append(conflicts[installedPkg.PkgInfo.Name], vpkg+" ("+pkgInfo.Name+")") conflicts[installedPkg.Name] = append(conflicts[installedPkg.Name], vpkg+" ("+pkgInfo.Name+")")
} }
} }
} }
@@ -429,12 +429,12 @@ func (operation *BPMOperation) ShowOperationSummary() {
fmt.Println("Warning: Operating in " + operation.RootDir) fmt.Println("Warning: Operating in " + operation.RootDir)
} }
if operation.GetTotalDownloadSize() > 0 { if operation.GetTotalDownloadSize() > 0 {
fmt.Printf("%s will be downloaded to complete this operation\n", bytesToHumanReadable(operation.GetTotalDownloadSize())) fmt.Printf("%s will be downloaded to complete this operation\n", BytesToHumanReadable(operation.GetTotalDownloadSize()))
} }
if operation.GetFinalActionSize(operation.RootDir) > 0 { if operation.GetFinalActionSize(operation.RootDir) > 0 {
fmt.Printf("A total of %s will be installed after the operation finishes\n", bytesToHumanReadable(operation.GetFinalActionSize(operation.RootDir))) fmt.Printf("A total of %s will be installed after the operation finishes\n", BytesToHumanReadable(operation.GetFinalActionSize(operation.RootDir)))
} else if operation.GetFinalActionSize(operation.RootDir) < 0 { } else if operation.GetFinalActionSize(operation.RootDir) < 0 {
fmt.Printf("A total of %s will be freed after the operation finishes\n", strings.TrimPrefix(bytesToHumanReadable(operation.GetFinalActionSize(operation.RootDir)), "-")) fmt.Printf("A total of %s will be freed after the operation finishes\n", strings.TrimPrefix(BytesToHumanReadable(operation.GetFinalActionSize(operation.RootDir)), "-"))
} }
} }
+28 -40
View File
@@ -536,60 +536,57 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) {
return pkgInfo, nil return pkgInfo, nil
} }
func (bpmpkg *BPMPackage) CreateReadableInfo(rootDir string, humanReadableSize bool) string { func (pkgInfo *PackageInfo) CreateReadableInfo(rootDir string) string {
ret := make([]string, 0) ret := make([]string, 0)
appendArray := func(label string, array []string) { appendArray := func(label string, array []string) {
if len(array) == 0 { if len(array) == 0 {
return return
} }
// Sort array
slices.Sort(array)
ret = append(ret, fmt.Sprintf("%s: %s", label, strings.Join(array, ", "))) ret = append(ret, fmt.Sprintf("%s: %s", label, strings.Join(array, ", ")))
} }
ret = append(ret, "Name: "+bpmpkg.PkgInfo.Name) ret = append(ret, "Name: "+pkgInfo.Name)
ret = append(ret, "Description: "+bpmpkg.PkgInfo.Description) ret = append(ret, "Description: "+pkgInfo.Description)
ret = append(ret, "Version: "+bpmpkg.PkgInfo.GetFullVersion()) ret = append(ret, "Version: "+pkgInfo.GetFullVersion())
if bpmpkg.PkgInfo.Url != "" { if pkgInfo.Url != "" {
ret = append(ret, "URL: "+bpmpkg.PkgInfo.Url) ret = append(ret, "URL: "+pkgInfo.Url)
} }
if bpmpkg.PkgInfo.License != "" { if pkgInfo.License != "" {
ret = append(ret, "License: "+bpmpkg.PkgInfo.License) ret = append(ret, "License: "+pkgInfo.License)
} }
ret = append(ret, "Architecture: "+bpmpkg.PkgInfo.Arch) ret = append(ret, "Architecture: "+pkgInfo.Arch)
if bpmpkg.PkgInfo.Type == "source" && bpmpkg.PkgInfo.OutputArch != "" && bpmpkg.PkgInfo.OutputArch != GetArch() { if pkgInfo.Type == "source" && pkgInfo.OutputArch != "" && pkgInfo.OutputArch != GetArch() {
ret = append(ret, "Output architecture: "+bpmpkg.PkgInfo.Arch) ret = append(ret, "Output architecture: "+pkgInfo.Arch)
} }
ret = append(ret, "Type: "+bpmpkg.PkgInfo.Type) ret = append(ret, "Type: "+pkgInfo.Type)
appendArray("Dependencies", bpmpkg.PkgInfo.Depends) appendArray("Dependencies", pkgInfo.Depends)
if bpmpkg.PkgInfo.Type == "source" { if pkgInfo.Type == "source" {
appendArray("Make Dependencies", bpmpkg.PkgInfo.MakeDepends) appendArray("Make Dependencies", pkgInfo.MakeDepends)
} }
appendArray("Optional dependencies", bpmpkg.PkgInfo.OptionalDepends) appendArray("Optional dependencies", pkgInfo.OptionalDepends)
dependants := bpmpkg.PkgInfo.GetPackageDependants(rootDir) dependants := pkgInfo.GetPackageDependants(rootDir)
if len(dependants) > 0 { if len(dependants) > 0 {
appendArray("Dependant packages", dependants) appendArray("Dependant packages", dependants)
} }
optionalDependants := bpmpkg.PkgInfo.GetPackageOptionalDependants(rootDir) optionalDependants := pkgInfo.GetPackageOptionalDependants(rootDir)
if len(optionalDependants) > 0 { if len(optionalDependants) > 0 {
appendArray("Optionally dependant packages", optionalDependants) appendArray("Optionally dependant packages", optionalDependants)
} }
appendArray("Conflicting packages", bpmpkg.PkgInfo.Conflicts) appendArray("Conflicting packages", pkgInfo.Conflicts)
appendArray("Provided packages", bpmpkg.PkgInfo.Provides) appendArray("Provided packages", pkgInfo.Provides)
appendArray("Replaces packages", bpmpkg.PkgInfo.Replaces) appendArray("Replaces packages", pkgInfo.Replaces)
if bpmpkg.PkgInfo.Type == "source" && len(bpmpkg.PkgInfo.SplitPackages) != 0 { if pkgInfo.Type == "source" && len(pkgInfo.SplitPackages) != 0 {
splitPkgs := make([]string, len(bpmpkg.PkgInfo.SplitPackages)) splitPkgs := make([]string, len(pkgInfo.SplitPackages))
for i, splitPkgInfo := range bpmpkg.PkgInfo.SplitPackages { for i, splitPkgInfo := range pkgInfo.SplitPackages {
splitPkgs[i] = splitPkgInfo.Name splitPkgs[i] = splitPkgInfo.Name
} }
appendArray("Split Packages", splitPkgs) appendArray("Split Packages", splitPkgs)
} }
if rootDir != "" && IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) { if rootDir != "" && IsPackageInstalled(pkgInfo.Name, rootDir) {
installationReason := GetInstallationReason(bpmpkg.PkgInfo.Name, rootDir) installationReason := GetInstallationReason(pkgInfo.Name, rootDir)
var installationReasonString string var installationReasonString string
switch installationReason { switch installationReason {
case InstallationReasonManual: case InstallationReasonManual:
@@ -603,16 +600,7 @@ func (bpmpkg *BPMPackage) CreateReadableInfo(rootDir string, humanReadableSize b
} }
ret = append(ret, "Installation Reason: "+installationReasonString) ret = append(ret, "Installation Reason: "+installationReasonString)
} }
if bpmpkg.PkgInfo.Type == "binary" {
installedSize := bpmpkg.GetInstalledSize()
var installedSizeStr string
if humanReadableSize {
installedSizeStr = bytesToHumanReadable(installedSize)
} else {
installedSizeStr = strconv.FormatInt(installedSize, 10)
}
ret = append(ret, "Installed size: "+installedSizeStr)
}
return strings.Join(ret, "\n") return strings.Join(ret, "\n")
} }
@@ -1007,7 +995,7 @@ func installPackage(filename, rootDir string, verbose, force bool) error {
} }
// Add or update package information for rootDir // Add or update package information for rootDir
localPackageInformation[rootDir][bpmpkg.PkgInfo.Name] = bpmpkg localPackageInformation[rootDir][bpmpkg.PkgInfo.Name] = bpmpkg.PkgInfo
return nil return nil
} }
+1 -1
View File
@@ -119,7 +119,7 @@ func stringSliceRemove(s []string, r string) []string {
return s return s
} }
func bytesToHumanReadable(b int64) string { func BytesToHumanReadable(b int64) string {
bf := float64(b) bf := float64(b)
for _, unit := range []string{"", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"} { for _, unit := range []string{"", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"} {
if math.Abs(bf) < 1024.0 { if math.Abs(bf) < 1024.0 {