Show installed size for binary packages

This commit is contained in:
2025-10-25 13:14:33 +03:00
parent 2db01fb0d4
commit c2d420d854
3 changed files with 63 additions and 39 deletions
+16 -13
View File
@@ -53,6 +53,7 @@ func main() {
currentFlagSet = flag.NewFlagSet("query", flag.ExitOnError) currentFlagSet = flag.NewFlagSet("query", flag.ExitOnError)
currentFlagSet.StringP("root", "R", "/", "Operate on specified root directory") currentFlagSet.StringP("root", "R", "/", "Operate on specified root directory")
currentFlagSet.BoolP("database", "d", false, "Show package information from remote databases") currentFlagSet.BoolP("database", "d", false, "Show package information from remote databases")
currentFlagSet.BoolP("human-readable", "h", false, "Show package installed size in a human readable format")
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Show information on the specified packages", os.Args[2:]) setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Show information on the specified packages", os.Args[2:])
showPackageInfo() showPackageInfo()
@@ -66,6 +67,7 @@ func main() {
currentFlagSet.Bool("manual", false, "Show packages installed as dependencies") currentFlagSet.Bool("manual", false, "Show packages installed as dependencies")
currentFlagSet.Bool("depends", false, "Show packages installed as dependencies") currentFlagSet.Bool("depends", false, "Show packages installed as dependencies")
currentFlagSet.Bool("make-depends", false, "Show packages installed as make dependencies") currentFlagSet.Bool("make-depends", false, "Show packages installed as make dependencies")
currentFlagSet.BoolP("human-readable", "h", false, "Show package installed size in a human readable format")
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "List packages", os.Args[2:]) setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "List packages", os.Args[2:])
showPackageList() showPackageList()
@@ -172,6 +174,7 @@ func showPackageInfo() {
// Get flags // Get flags
rootDir, _ := currentFlagSet.GetString("root") rootDir, _ := currentFlagSet.GetString("root")
showDatabaseInfo, _ := currentFlagSet.GetBool("database") showDatabaseInfo, _ := currentFlagSet.GetBool("database")
showHumanReadableSize, _ := currentFlagSet.GetBool("human-readable")
// Get packages // Get packages
packages := currentFlagSet.Args() packages := currentFlagSet.Args()
@@ -204,30 +207,29 @@ func showPackageInfo() {
if n != 0 { if n != 0 {
fmt.Println() fmt.Println()
} }
fmt.Println(entry.CreateReadableInfo(rootDir)) fmt.Println(entry.CreateReadableInfo(rootDir, showHumanReadableSize))
return return
} }
var info *bpmlib.PackageInfo var bpmpkg *bpmlib.BPMPackage
isFile := false isFile := false
if stat, err := os.Stat(pkg); err == nil && !stat.IsDir() { if stat, err := os.Stat(pkg); err == nil && !stat.IsDir() {
bpmpkg, err := bpmlib.ReadPackage(pkg) bpmpkg, err = bpmlib.ReadPackage(pkg)
if err != nil { if err != nil {
log.Printf("Error: could not read package: %s\n", err) log.Printf("Error: could not read package: %s\n", err)
exitCode = 1 exitCode = 1
return return
} }
info = bpmpkg.PkgInfo
isFile = true isFile = true
} else { } else {
if isVirtual, p := bpmlib.IsVirtualPackage(pkg, rootDir); isVirtual { if isVirtual, p := bpmlib.IsVirtualPackage(pkg, rootDir); isVirtual {
info = bpmlib.GetPackageInfo(p, rootDir) bpmpkg = bpmlib.GetPackage(p, rootDir)
} else { } else {
info = bpmlib.GetPackageInfo(pkg, rootDir) bpmpkg = bpmlib.GetPackage(pkg, rootDir)
} }
} }
if info == nil { if bpmpkg == nil {
log.Printf("Error: package (%s) is not installed\n", pkg) log.Printf("Error: package (%s) is not installed\n", pkg)
exitCode = 1 exitCode = 1
return return
@@ -244,7 +246,7 @@ func showPackageInfo() {
} }
fmt.Println("File: " + abs) fmt.Println("File: " + abs)
} }
fmt.Println(info.CreateReadableInfo(rootDir)) fmt.Println(bpmpkg.CreateReadableInfo(rootDir, showHumanReadableSize))
} }
} }
@@ -257,6 +259,7 @@ func showPackageList() {
showManual, _ := currentFlagSet.GetBool("manual") showManual, _ := currentFlagSet.GetBool("manual")
showDepends, _ := currentFlagSet.GetBool("depends") showDepends, _ := currentFlagSet.GetBool("depends")
showMakeDepends, _ := currentFlagSet.GetBool("make-depends") showMakeDepends, _ := currentFlagSet.GetBool("make-depends")
showHumanReadableSize, _ := currentFlagSet.GetBool("human-readable")
if !isFlagSet(currentFlagSet, "manual") && !isFlagSet(currentFlagSet, "depends") && !isFlagSet(currentFlagSet, "make-depends") { if !isFlagSet(currentFlagSet, "manual") && !isFlagSet(currentFlagSet, "depends") && !isFlagSet(currentFlagSet, "make-depends") {
showManual = true showManual = true
@@ -321,7 +324,7 @@ func showPackageList() {
if n != 0 { if n != 0 {
fmt.Println() fmt.Println()
} }
fmt.Println(entry.CreateReadableInfo(rootDir)) fmt.Println(entry.CreateReadableInfo(rootDir, showHumanReadableSize))
} }
} else { } else {
if len(installedPackages) == 0 { if len(installedPackages) == 0 {
@@ -329,13 +332,13 @@ func showPackageList() {
return return
} }
for n, pkg := range installedPackages { for n, pkg := range installedPackages {
info := bpmlib.GetPackageInfo(pkg, rootDir) bpmpkg := bpmlib.GetPackage(pkg, rootDir)
if info == nil { if bpmpkg == nil {
fmt.Printf("Package (%s) could not be found\n", pkg) fmt.Printf("Package (%s) could not be found\n", pkg)
continue continue
} }
installationReason := bpmlib.GetInstallationReason(info.Name, rootDir) 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 {
@@ -349,7 +352,7 @@ func showPackageList() {
if n != 0 { if n != 0 {
fmt.Println() fmt.Println()
} }
fmt.Println(info.CreateReadableInfo(rootDir)) fmt.Println(bpmpkg.CreateReadableInfo(rootDir, showHumanReadableSize))
} }
} }
} }
+12 -1
View File
@@ -8,6 +8,7 @@ import (
"os" "os"
"path" "path"
"slices" "slices"
"strconv"
"strings" "strings"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@@ -280,7 +281,7 @@ func (entry *BPMDatabaseEntry) GetEntryDependants() (dependants []string) {
return dependants return dependants
} }
func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string) string { func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string, humanReadableSize bool) string {
ret := make([]string, 0) ret := make([]string, 0)
appendArray := func(label string, array []string, sort bool) { appendArray := func(label string, array []string, sort bool) {
if len(array) == 0 { if len(array) == 0 {
@@ -346,5 +347,15 @@ func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string) string {
} }
ret = append(ret, "Installation Reason: "+installationReasonString) ret = append(ret, "Installation Reason: "+installationReasonString)
} }
if entry.Info.Type == "binary" {
installedSize := int64(entry.InstalledSize)
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")
} }
+35 -25
View File
@@ -507,7 +507,7 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) {
return pkgInfo, nil return pkgInfo, nil
} }
func (pkgInfo *PackageInfo) CreateReadableInfo(rootDir string) string { func (bpmpkg *BPMPackage) CreateReadableInfo(rootDir string, humanReadableSize bool) 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 {
@@ -520,43 +520,43 @@ func (pkgInfo *PackageInfo) CreateReadableInfo(rootDir string) string {
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: "+pkgInfo.Name) ret = append(ret, "Name: "+bpmpkg.PkgInfo.Name)
ret = append(ret, "Description: "+pkgInfo.Description) ret = append(ret, "Description: "+bpmpkg.PkgInfo.Description)
ret = append(ret, "Version: "+pkgInfo.GetFullVersion()) ret = append(ret, "Version: "+bpmpkg.PkgInfo.GetFullVersion())
if pkgInfo.Url != "" { if bpmpkg.PkgInfo.Url != "" {
ret = append(ret, "URL: "+pkgInfo.Url) ret = append(ret, "URL: "+bpmpkg.PkgInfo.Url)
} }
if pkgInfo.License != "" { if bpmpkg.PkgInfo.License != "" {
ret = append(ret, "License: "+pkgInfo.License) ret = append(ret, "License: "+bpmpkg.PkgInfo.License)
} }
ret = append(ret, "Architecture: "+pkgInfo.Arch) ret = append(ret, "Architecture: "+bpmpkg.PkgInfo.Arch)
if pkgInfo.Type == "source" && pkgInfo.OutputArch != "" && pkgInfo.OutputArch != GetArch() { if bpmpkg.PkgInfo.Type == "source" && bpmpkg.PkgInfo.OutputArch != "" && bpmpkg.PkgInfo.OutputArch != GetArch() {
ret = append(ret, "Output architecture: "+pkgInfo.Arch) ret = append(ret, "Output architecture: "+bpmpkg.PkgInfo.Arch)
} }
ret = append(ret, "Type: "+pkgInfo.Type) ret = append(ret, "Type: "+bpmpkg.PkgInfo.Type)
appendArray("Dependencies", pkgInfo.Depends) appendArray("Dependencies", bpmpkg.PkgInfo.Depends)
if pkgInfo.Type == "source" { if bpmpkg.PkgInfo.Type == "source" {
appendArray("Make Dependencies", pkgInfo.MakeDepends) appendArray("Make Dependencies", bpmpkg.PkgInfo.MakeDepends)
} }
appendArray("Optional dependencies", pkgInfo.OptionalDepends) appendArray("Optional dependencies", bpmpkg.PkgInfo.OptionalDepends)
dependants := pkgInfo.GetPackageDependants(rootDir) dependants := bpmpkg.PkgInfo.GetPackageDependants(rootDir)
if len(dependants) > 0 { if len(dependants) > 0 {
appendArray("Dependant packages", dependants) appendArray("Dependant packages", dependants)
} }
appendArray("Conflicting packages", pkgInfo.Conflicts) appendArray("Conflicting packages", bpmpkg.PkgInfo.Conflicts)
appendArray("Provided packages", pkgInfo.Provides) appendArray("Provided packages", bpmpkg.PkgInfo.Provides)
appendArray("Replaces packages", pkgInfo.Replaces) appendArray("Replaces packages", bpmpkg.PkgInfo.Replaces)
if pkgInfo.Type == "source" && len(pkgInfo.SplitPackages) != 0 { if bpmpkg.PkgInfo.Type == "source" && len(bpmpkg.PkgInfo.SplitPackages) != 0 {
splitPkgs := make([]string, len(pkgInfo.SplitPackages)) splitPkgs := make([]string, len(bpmpkg.PkgInfo.SplitPackages))
for i, splitPkgInfo := range pkgInfo.SplitPackages { for i, splitPkgInfo := range bpmpkg.PkgInfo.SplitPackages {
splitPkgs[i] = splitPkgInfo.Name splitPkgs[i] = splitPkgInfo.Name
} }
appendArray("Split Packages", splitPkgs) appendArray("Split Packages", splitPkgs)
} }
if rootDir != "" && IsPackageInstalled(pkgInfo.Name, rootDir) { if rootDir != "" && IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) {
installationReason := GetInstallationReason(pkgInfo.Name, rootDir) installationReason := GetInstallationReason(bpmpkg.PkgInfo.Name, rootDir)
var installationReasonString string var installationReasonString string
switch installationReason { switch installationReason {
case InstallationReasonManual: case InstallationReasonManual:
@@ -570,6 +570,16 @@ func (pkgInfo *PackageInfo) CreateReadableInfo(rootDir string) string {
} }
ret = append(ret, "Installation Reason: "+installationReasonString) ret = append(ret, "Installation Reason: "+installationReasonString)
} }
if bpmpkg.PkgInfo.Type == "binary" {
installedSize := int64(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")
} }