diff --git a/src/bpm/main.go b/src/bpm/main.go index 34b87b0..8f8d016 100644 --- a/src/bpm/main.go +++ b/src/bpm/main.go @@ -53,6 +53,7 @@ func main() { currentFlagSet = flag.NewFlagSet("query", flag.ExitOnError) currentFlagSet.StringP("root", "R", "/", "Operate on specified root directory") 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 ", subcommand), "Show information on the specified packages", os.Args[2:]) showPackageInfo() @@ -66,6 +67,7 @@ func main() { currentFlagSet.Bool("manual", 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.BoolP("human-readable", "h", false, "Show package installed size in a human readable format") setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s ", subcommand), "List packages", os.Args[2:]) showPackageList() @@ -172,6 +174,7 @@ func showPackageInfo() { // Get flags rootDir, _ := currentFlagSet.GetString("root") showDatabaseInfo, _ := currentFlagSet.GetBool("database") + showHumanReadableSize, _ := currentFlagSet.GetBool("human-readable") // Get packages packages := currentFlagSet.Args() @@ -204,30 +207,29 @@ func showPackageInfo() { if n != 0 { fmt.Println() } - fmt.Println(entry.CreateReadableInfo(rootDir)) + fmt.Println(entry.CreateReadableInfo(rootDir, showHumanReadableSize)) return } - var info *bpmlib.PackageInfo + var bpmpkg *bpmlib.BPMPackage isFile := false if stat, err := os.Stat(pkg); err == nil && !stat.IsDir() { - bpmpkg, err := bpmlib.ReadPackage(pkg) + bpmpkg, err = bpmlib.ReadPackage(pkg) if err != nil { log.Printf("Error: could not read package: %s\n", err) exitCode = 1 return } - info = bpmpkg.PkgInfo isFile = true } else { if isVirtual, p := bpmlib.IsVirtualPackage(pkg, rootDir); isVirtual { - info = bpmlib.GetPackageInfo(p, rootDir) + bpmpkg = bpmlib.GetPackage(p, rootDir) } 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) exitCode = 1 return @@ -244,7 +246,7 @@ func showPackageInfo() { } 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") showDepends, _ := currentFlagSet.GetBool("depends") showMakeDepends, _ := currentFlagSet.GetBool("make-depends") + showHumanReadableSize, _ := currentFlagSet.GetBool("human-readable") if !isFlagSet(currentFlagSet, "manual") && !isFlagSet(currentFlagSet, "depends") && !isFlagSet(currentFlagSet, "make-depends") { showManual = true @@ -321,7 +324,7 @@ func showPackageList() { if n != 0 { fmt.Println() } - fmt.Println(entry.CreateReadableInfo(rootDir)) + fmt.Println(entry.CreateReadableInfo(rootDir, showHumanReadableSize)) } } else { if len(installedPackages) == 0 { @@ -329,13 +332,13 @@ func showPackageList() { return } for n, pkg := range installedPackages { - info := bpmlib.GetPackageInfo(pkg, rootDir) - if info == nil { + bpmpkg := bpmlib.GetPackage(pkg, rootDir) + if bpmpkg == nil { fmt.Printf("Package (%s) could not be found\n", pkg) continue } - installationReason := bpmlib.GetInstallationReason(info.Name, rootDir) + installationReason := bpmlib.GetInstallationReason(bpmpkg.PkgInfo.Name, rootDir) if installationReason == bpmlib.InstallationReasonManual && !showManual { continue } else if installationReason == bpmlib.InstallationReasonDependency && !showDepends { @@ -349,7 +352,7 @@ func showPackageList() { if n != 0 { fmt.Println() } - fmt.Println(info.CreateReadableInfo(rootDir)) + fmt.Println(bpmpkg.CreateReadableInfo(rootDir, showHumanReadableSize)) } } } diff --git a/src/bpmlib/databases.go b/src/bpmlib/databases.go index 3d78f6e..fd0726a 100644 --- a/src/bpmlib/databases.go +++ b/src/bpmlib/databases.go @@ -8,6 +8,7 @@ import ( "os" "path" "slices" + "strconv" "strings" "gopkg.in/yaml.v3" @@ -280,7 +281,7 @@ func (entry *BPMDatabaseEntry) GetEntryDependants() (dependants []string) { return dependants } -func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string) string { +func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string, humanReadableSize bool) string { ret := make([]string, 0) appendArray := func(label string, array []string, sort bool) { if len(array) == 0 { @@ -346,5 +347,15 @@ func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string) string { } 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") } diff --git a/src/bpmlib/packages.go b/src/bpmlib/packages.go index 73e2ba5..005cd2d 100644 --- a/src/bpmlib/packages.go +++ b/src/bpmlib/packages.go @@ -507,7 +507,7 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) { return pkgInfo, nil } -func (pkgInfo *PackageInfo) CreateReadableInfo(rootDir string) string { +func (bpmpkg *BPMPackage) CreateReadableInfo(rootDir string, humanReadableSize bool) string { ret := make([]string, 0) appendArray := func(label string, array []string) { 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, "Name: "+pkgInfo.Name) - ret = append(ret, "Description: "+pkgInfo.Description) - ret = append(ret, "Version: "+pkgInfo.GetFullVersion()) - if pkgInfo.Url != "" { - ret = append(ret, "URL: "+pkgInfo.Url) + ret = append(ret, "Name: "+bpmpkg.PkgInfo.Name) + ret = append(ret, "Description: "+bpmpkg.PkgInfo.Description) + ret = append(ret, "Version: "+bpmpkg.PkgInfo.GetFullVersion()) + if bpmpkg.PkgInfo.Url != "" { + ret = append(ret, "URL: "+bpmpkg.PkgInfo.Url) } - if pkgInfo.License != "" { - ret = append(ret, "License: "+pkgInfo.License) + if bpmpkg.PkgInfo.License != "" { + ret = append(ret, "License: "+bpmpkg.PkgInfo.License) } - ret = append(ret, "Architecture: "+pkgInfo.Arch) - if pkgInfo.Type == "source" && pkgInfo.OutputArch != "" && pkgInfo.OutputArch != GetArch() { - ret = append(ret, "Output architecture: "+pkgInfo.Arch) + ret = append(ret, "Architecture: "+bpmpkg.PkgInfo.Arch) + if bpmpkg.PkgInfo.Type == "source" && bpmpkg.PkgInfo.OutputArch != "" && bpmpkg.PkgInfo.OutputArch != GetArch() { + ret = append(ret, "Output architecture: "+bpmpkg.PkgInfo.Arch) } - ret = append(ret, "Type: "+pkgInfo.Type) - appendArray("Dependencies", pkgInfo.Depends) - if pkgInfo.Type == "source" { - appendArray("Make Dependencies", pkgInfo.MakeDepends) + ret = append(ret, "Type: "+bpmpkg.PkgInfo.Type) + appendArray("Dependencies", bpmpkg.PkgInfo.Depends) + if bpmpkg.PkgInfo.Type == "source" { + appendArray("Make Dependencies", bpmpkg.PkgInfo.MakeDepends) } - appendArray("Optional dependencies", pkgInfo.OptionalDepends) - dependants := pkgInfo.GetPackageDependants(rootDir) + appendArray("Optional dependencies", bpmpkg.PkgInfo.OptionalDepends) + dependants := bpmpkg.PkgInfo.GetPackageDependants(rootDir) if len(dependants) > 0 { appendArray("Dependant packages", dependants) } - appendArray("Conflicting packages", pkgInfo.Conflicts) - appendArray("Provided packages", pkgInfo.Provides) - appendArray("Replaces packages", pkgInfo.Replaces) + appendArray("Conflicting packages", bpmpkg.PkgInfo.Conflicts) + appendArray("Provided packages", bpmpkg.PkgInfo.Provides) + appendArray("Replaces packages", bpmpkg.PkgInfo.Replaces) - if pkgInfo.Type == "source" && len(pkgInfo.SplitPackages) != 0 { - splitPkgs := make([]string, len(pkgInfo.SplitPackages)) - for i, splitPkgInfo := range pkgInfo.SplitPackages { + if bpmpkg.PkgInfo.Type == "source" && len(bpmpkg.PkgInfo.SplitPackages) != 0 { + splitPkgs := make([]string, len(bpmpkg.PkgInfo.SplitPackages)) + for i, splitPkgInfo := range bpmpkg.PkgInfo.SplitPackages { splitPkgs[i] = splitPkgInfo.Name } appendArray("Split Packages", splitPkgs) } - if rootDir != "" && IsPackageInstalled(pkgInfo.Name, rootDir) { - installationReason := GetInstallationReason(pkgInfo.Name, rootDir) + if rootDir != "" && IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) { + installationReason := GetInstallationReason(bpmpkg.PkgInfo.Name, rootDir) var installationReasonString string switch installationReason { case InstallationReasonManual: @@ -570,6 +570,16 @@ func (pkgInfo *PackageInfo) CreateReadableInfo(rootDir string) string { } 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") }