From ab75193022538eacb33feaee8046477607b68fcf Mon Sep 17 00:00:00 2001 From: EnumDev Date: Tue, 27 Aug 2024 11:07:53 +0300 Subject: [PATCH] Added installation reason and improved console output readability --- bpm_utils/package_utils.go | 94 +++++++++++++++++++++++++++++++++++++- main.go | 34 ++++++++++---- 2 files changed, 118 insertions(+), 10 deletions(-) diff --git a/bpm_utils/package_utils.go b/bpm_utils/package_utils.go index 5d949e0..9902bf0 100644 --- a/bpm_utils/package_utils.go +++ b/bpm_utils/package_utils.go @@ -39,6 +39,43 @@ type PackageInfo struct { Provides []string `yaml:"provides,omitempty"` } +type InstallationReason string + +const ( + Manual InstallationReason = "manual" + Dependency InstallationReason = "dependency" + Unknown InstallationReason = "unknown" +) + +func GetInstallationReason(pkg, rootDir string) InstallationReason { + installedDir := path.Join(rootDir, "var/lib/bpm/installed/") + pkgDir := path.Join(installedDir, pkg) + if stat, err := os.Stat(path.Join(pkgDir, "installation_reason")); err != nil || stat.IsDir() { + return Manual + } + bytes, err := os.ReadFile(path.Join(pkgDir, "installation_reason")) + if err != nil { + return Unknown + } + reason := string(bytes) + if reason == "manual" { + return Manual + } else if reason == "dependency" { + return Dependency + } + return Unknown +} + +func SetInstallationReason(pkg string, reason InstallationReason, rootDir string) error { + installedDir := path.Join(rootDir, "var/lib/bpm/installed/") + pkgDir := path.Join(installedDir, pkg) + err := os.WriteFile(path.Join(pkgDir, "installation_reason"), []byte(reason), 0644) + if err != nil { + return err + } + return nil +} + func GetPackageInfoRaw(filename string) (string, error) { if _, err := os.Stat(filename); os.IsNotExist(err) { return "", err @@ -316,7 +353,7 @@ func ReadPackageInfo(contents string, defaultValues bool) (*PackageInfo, error) return &pkgInfo, nil } -func CreateInfoFile(pkgInfo PackageInfo) string { +func CreateInfoFile(pkgInfo *PackageInfo) string { bytes, err := yaml.Marshal(&pkgInfo) if err != nil { return "" @@ -324,6 +361,59 @@ func CreateInfoFile(pkgInfo PackageInfo) string { return string(bytes) } +func CreateReadableInfo(showArchitecture, showType, showPackageRelations, showRemoteInfo, showInstallationReason bool, pkgInfo *PackageInfo, rootDir string) string { + ret := make([]string, 0) + appendArray := func(label string, array []string) { + if len(array) == 0 { + return + } + ret = append(ret, fmt.Sprintf("%s: %s", label, strings.Join(array, ", "))) + } + appendMap := func(label string, m map[string][]string) { + if len(m) == 0 { + return + } + ret = append(ret, label+":") + for k, v := range m { + if len(v) == 0 { + continue + } + ret = append(ret, fmt.Sprintf(" %s: %s", k, strings.Join(v, ", "))) + } + } + ret = append(ret, "Name: "+pkgInfo.Name) + ret = append(ret, "Description: "+pkgInfo.Description) + ret = append(ret, "Version: "+pkgInfo.Version) + ret = append(ret, "URL: "+pkgInfo.Url) + ret = append(ret, "License: "+pkgInfo.License) + if showArchitecture { + ret = append(ret, "Architecture: "+pkgInfo.Arch) + } + if showType { + ret = append(ret, "Type: "+pkgInfo.Type) + } + if showPackageRelations { + appendArray("Dependencies", pkgInfo.Depends) + appendArray("Make Dependencies", pkgInfo.MakeDepends) + appendArray("Provided packages", pkgInfo.Provides) + appendArray("Conflicting packages", pkgInfo.Conflicts) + appendArray("Optional dependencies", pkgInfo.Optional) + appendMap("Conditional dependencies", pkgInfo.ConditionalDepends) + appendMap("Conditional make dependencies", pkgInfo.ConditionalMakeDepends) + appendMap("Conditional conflicting packages", pkgInfo.ConditionalConflicts) + appendMap("Conditional optional dependencies", pkgInfo.ConditionalOptional) + } + if showInstallationReason { + if IsPackageInstalled(pkgInfo.Name, rootDir) { + ret = append(ret, "Installed: yes") + ret = append(ret, "Installation Reason: "+string(GetInstallationReason(pkgInfo.Name, rootDir))) + } else { + ret = append(ret, "Installed: no") + } + } + return strings.Join(ret, "\n") +} + func extractPackage(pkgInfo *PackageInfo, verbose bool, filename, rootDir string) (error, []string) { var files []string if !IsPackageInstalled(pkgInfo.Name, rootDir) { @@ -848,7 +938,7 @@ fi compiledInfo = *pkgInfo compiledInfo.Type = "binary" compiledInfo.Arch = GetArch() - err = os.WriteFile(path.Join(temp, "pkg.info"), []byte(CreateInfoFile(compiledInfo)), 0644) + err = os.WriteFile(path.Join(temp, "pkg.info"), []byte(CreateInfoFile(&compiledInfo)), 0644) if err != nil { return err, nil } diff --git a/main.go b/main.go index bb14fa0..e1ee1cf 100644 --- a/main.go +++ b/main.go @@ -30,6 +30,7 @@ var buildSource = false var skipCheck = false var keepTempDir = false var forceInstall = false +var showInstalled = false var pkgListNumbers = false var pkgListNames = false @@ -82,12 +83,27 @@ func resolveCommand() { return } for n, pkg := range packages { - info := bpm_utils.GetPackageInfo(pkg, rootDir, false) - if info == nil { - fmt.Printf("Package (%s) could not be found\n", pkg) - continue + var info *bpm_utils.PackageInfo + if _, err := os.Stat(pkg); err == nil && !showInstalled { + info, err = bpm_utils.ReadPackage(pkg) + if err != nil { + fmt.Printf("File (%s) could not be read\n", pkg) + continue + } + + } else { + info = bpm_utils.GetPackageInfo(pkg, rootDir, false) + if info == nil { + fmt.Printf("Package (%s) could not be found\n", pkg) + continue + } + } + fmt.Println("----------------") + if showInstalled { + fmt.Println(bpm_utils.CreateReadableInfo(false, false, true, false, true, info, rootDir)) + } else { + fmt.Println(bpm_utils.CreateReadableInfo(true, true, true, true, true, info, rootDir)) } - fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*info)) if n == len(packages)-1 { fmt.Println("----------------") } @@ -115,7 +131,7 @@ func resolveCommand() { fmt.Printf("Package (%s) could not be found\n", pkg) continue } - fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*info)) + fmt.Println("----------------\n" + bpm_utils.CreateReadableInfo(true, true, true, true, true, info, rootDir)) if n == len(packages)-1 { fmt.Println("----------------") } @@ -137,7 +153,7 @@ func resolveCommand() { log.Fatalf("Could not read package\nError: %s\n", err) } if !yesAll { - fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*pkgInfo)) + fmt.Println("----------------\n" + bpm_utils.CreateReadableInfo(true, true, true, true, false, pkgInfo, rootDir)) fmt.Println("----------------") } verb := "install" @@ -238,7 +254,7 @@ func resolveCommand() { fmt.Printf("Package (%s) could not be found\n", pkg) continue } - fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*pkgInfo)) + fmt.Println("----------------\n" + bpm_utils.CreateReadableInfo(true, true, true, true, true, pkgInfo, rootDir)) fmt.Println("----------------") if rootDir != "/" { fmt.Println("Warning: Operating in " + rootDir) @@ -319,6 +335,7 @@ func printHelp() { fmt.Println("-> bpm version | shows information on the installed version of bpm") fmt.Println("-> bpm info [-R] | shows information on an installed package") fmt.Println(" -R= lets you define the root path which will be used") + fmt.Println(" -i shows information about the currently installed package") fmt.Println("-> bpm list [-R, -c, -n] | lists all installed packages") fmt.Println(" -R= lets you define the root path which will be used") fmt.Println(" -c lists the amount of installed packages") @@ -351,6 +368,7 @@ func resolveFlags() { // Info flags infoFlagSet := flag.NewFlagSet("Info flags", flag.ExitOnError) infoFlagSet.StringVar(&rootDir, "R", "/", "Set the destination root") + infoFlagSet.BoolVar(&showInstalled, "i", false, "Shows information about the currently installed package") infoFlagSet.Usage = printHelp // Install flags installFlagSet := flag.NewFlagSet("Install flags", flag.ExitOnError)