From 2d35ac12a1d1b9dc4288504191d2973d1758bf5b Mon Sep 17 00:00:00 2001 From: EnumDev Date: Mon, 7 Oct 2024 14:47:57 +0300 Subject: [PATCH 1/5] Provided packages should now function correctly --- utils/repo_utils.go | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/utils/repo_utils.go b/utils/repo_utils.go index 80fd42b..d28ae00 100644 --- a/utils/repo_utils.go +++ b/utils/repo_utils.go @@ -8,6 +8,7 @@ import ( "net/url" "os" "path" + "sort" "strings" ) @@ -19,8 +20,9 @@ type Repository struct { } type RepositoryEntry struct { - Info *PackageInfo `yaml:"info"` - Download string `yaml:"download"` + Info *PackageInfo `yaml:"info"` + Download string `yaml:"download"` + IsVirtualPackage bool `yaml:"-"` } func (repo *Repository) ContainsPackage(pkg string) bool { @@ -39,6 +41,8 @@ func (repo *Repository) ReadLocalDatabase() error { return err } + virtualPackages := make(map[string][]string) + data := string(bytes) for _, b := range strings.Split(data, "---") { entry := RepositoryEntry{ @@ -58,14 +62,32 @@ func (repo *Repository) ReadLocalDatabase() error { Conflicts: make([]string, 0), Provides: make([]string, 0), }, - Download: "", + Download: "", + IsVirtualPackage: false, } err := yaml.Unmarshal([]byte(b), &entry) if err != nil { return err } + + for _, p := range entry.Info.Provides { + virtualPackages[p] = append(virtualPackages[p], entry.Info.Name) + } repo.Entries[entry.Info.Name] = &entry } + + for key, value := range virtualPackages { + if _, ok := repo.Entries[key]; ok { + continue + } + sort.Strings(value) + entry := RepositoryEntry{ + Info: repo.Entries[value[0]].Info, + Download: repo.Entries[value[0]].Download, + IsVirtualPackage: true, + } + repo.Entries[key] = &entry + } return nil } From e6cfd112ea9b57ea47a9a4e1cf292257899d708f Mon Sep 17 00:00:00 2001 From: EnumDev Date: Mon, 7 Oct 2024 19:12:17 +0300 Subject: [PATCH 2/5] Improved version comparison --- go.mod | 1 + go.sum | 4 ++++ main.go | 24 ++++++++++++++++-------- utils/package_utils.go | 8 ++++++++ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 017c769..eb5bc0a 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,6 @@ go 1.22 require ( github.com/elliotchance/orderedmap/v2 v2.4.0 // indirect + github.com/knqyf263/go-rpm-version v0.0.0-20240918084003-2afd7dc6a38f // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e437a0b..138d9eb 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,9 @@ github.com/elliotchance/orderedmap/v2 v2.4.0 h1:6tUmMwD9F998FNpwFxA5E6NQvSpk2PVw7RKsVq3+2Cw= github.com/elliotchance/orderedmap/v2 v2.4.0/go.mod h1:85lZyVbpGaGvHvnKa7Qhx7zncAdBIBq6u56Hb1PRU5Q= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/knqyf263/go-rpm-version v0.0.0-20240918084003-2afd7dc6a38f h1:xt29M2T6STgldg+WEP51gGePQCsQvklmP2eIhPIBK3g= +github.com/knqyf263/go-rpm-version v0.0.0-20240918084003-2afd7dc6a38f/go.mod h1:i4sF0l1fFnY1aiw08QQSwVAFxHEm311Me3WsU/X7nL0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index edff4ae..9619279 100644 --- a/main.go +++ b/main.go @@ -47,8 +47,8 @@ func main() { type commandType uint8 const ( - help commandType = iota - version + _default commandType = iota + help info list search @@ -62,7 +62,7 @@ const ( func getCommandType() commandType { switch subcommand { case "version": - return version + return _default case "info": return info case "list": @@ -86,7 +86,7 @@ func getCommandType() commandType { func resolveCommand() { switch getCommandType() { - case version: + case _default: fmt.Println("Bubble Package Manager (BPM)") fmt.Println("Version: " + bpmVer) case info: @@ -270,11 +270,15 @@ func resolveCommand() { } sourceInfo = "(From Source)" } + if installedInfo == nil { fmt.Printf("%s: %s (Install) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo) - } else if strings.Compare(pkgInfo.GetFullVersion(), installedInfo.GetFullVersion()) < 0 { + } + + comparison := utils.ComparePackageVersions(*pkgInfo, *installedInfo) + if comparison < 0 { fmt.Printf("%s: %s -> %s (Downgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo) - } else if strings.Compare(pkgInfo.GetFullVersion(), installedInfo.GetFullVersion()) > 0 { + } else if comparison > 0 { fmt.Printf("%s: %s -> %s (Upgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo) } else { fmt.Printf("%s: %s (Reinstall) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo) @@ -383,7 +387,9 @@ func resolveCommand() { if installedInfo == nil { log.Fatalf("Error: could not get package info for (%s)\n", pkg) } - if strings.Compare(entry.Info.GetFullVersion(), installedInfo.GetFullVersion()) > 0 { + + comparison := utils.ComparePackageVersions(*entry.Info, *installedInfo) + if comparison > 0 { toUpdate.Set(entry.Info.Name, &struct { isDependency bool entry *utils.RepositoryEntry @@ -440,7 +446,9 @@ func resolveCommand() { fmt.Printf("%s: %s (Install) %s\n", value.entry.Info.Name, value.entry.Info.GetFullVersion(), sourceInfo) continue } - if strings.Compare(value.entry.Info.GetFullVersion(), installedInfo.GetFullVersion()) > 0 { + + comparison := utils.ComparePackageVersions(*value.entry.Info, *installedInfo) + if comparison > 0 { fmt.Printf("%s: %s -> %s (Upgrade) %s\n", value.entry.Info.Name, installedInfo.GetFullVersion(), value.entry.Info.GetFullVersion(), sourceInfo) } else if reinstall { fmt.Printf("%s: %s -> %s (Reinstall) %s\n", value.entry.Info.Name, installedInfo.GetFullVersion(), value.entry.Info.GetFullVersion(), sourceInfo) diff --git a/utils/package_utils.go b/utils/package_utils.go index 03881bf..3b0ca9b 100644 --- a/utils/package_utils.go +++ b/utils/package_utils.go @@ -6,6 +6,7 @@ import ( "compress/gzip" "errors" "fmt" + version "github.com/knqyf263/go-rpm-version" "gopkg.in/yaml.v3" "io" "io/fs" @@ -48,6 +49,13 @@ const ( Unknown InstallationReason = "unknown" ) +func ComparePackageVersions(info1, info2 PackageInfo) int { + v1 := version.NewVersion(info1.GetFullVersion()) + v2 := version.NewVersion(info2.GetFullVersion()) + + return v1.Compare(v2) +} + func GetInstallationReason(pkg, rootDir string) InstallationReason { installedDir := path.Join(rootDir, "var/lib/bpm/installed/") pkgDir := path.Join(installedDir, pkg) From e1726ddce58ae50cb8a92b14d9e81bcb4f7268ec Mon Sep 17 00:00:00 2001 From: EnumDev Date: Mon, 7 Oct 2024 19:30:42 +0300 Subject: [PATCH 3/5] Add pre_remove.sh package scripts --- utils/package_utils.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/utils/package_utils.go b/utils/package_utils.go index 3b0ca9b..b550fe7 100644 --- a/utils/package_utils.go +++ b/utils/package_utils.go @@ -316,6 +316,12 @@ func ExecutePackageScripts(filename, rootDir string, operation Operation, postOp } } } else if operation == Remove { + if val, ok := scripts["pre_remove.sh"]; !postOperation && ok { + err := run("pre_remove.sh", val) + if err != nil { + return err + } + } if val, ok := scripts["post_remove.sh"]; postOperation && ok { err := run("post_remove.sh", val) if err != nil { From 4793424f3d5923d542db4517d7dad98bfc4d6db1 Mon Sep 17 00:00:00 2001 From: EnumDev Date: Tue, 8 Oct 2024 11:10:49 +0300 Subject: [PATCH 4/5] Fixed error when installing new package --- main.go | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/main.go b/main.go index 9619279..e042b5e 100644 --- a/main.go +++ b/main.go @@ -273,15 +273,15 @@ func resolveCommand() { if installedInfo == nil { fmt.Printf("%s: %s (Install) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo) - } - - comparison := utils.ComparePackageVersions(*pkgInfo, *installedInfo) - if comparison < 0 { - fmt.Printf("%s: %s -> %s (Downgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo) - } else if comparison > 0 { - fmt.Printf("%s: %s -> %s (Upgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo) } else { - fmt.Printf("%s: %s (Reinstall) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo) + comparison := utils.ComparePackageVersions(*pkgInfo, *installedInfo) + if comparison < 0 { + fmt.Printf("%s: %s -> %s (Downgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo) + } else if comparison > 0 { + fmt.Printf("%s: %s -> %s (Upgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo) + } else { + fmt.Printf("%s: %s (Reinstall) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo) + } } } if rootDir != "/" { @@ -386,19 +386,19 @@ func resolveCommand() { installedInfo := utils.GetPackageInfo(pkg, rootDir, true) if installedInfo == nil { log.Fatalf("Error: could not get package info for (%s)\n", pkg) - } - - comparison := utils.ComparePackageVersions(*entry.Info, *installedInfo) - if comparison > 0 { - toUpdate.Set(entry.Info.Name, &struct { - isDependency bool - entry *utils.RepositoryEntry - }{isDependency: false, entry: entry}) - } else if reinstall { - toUpdate.Set(entry.Info.Name, &struct { - isDependency bool - entry *utils.RepositoryEntry - }{isDependency: false, entry: entry}) + } else { + comparison := utils.ComparePackageVersions(*entry.Info, *installedInfo) + if comparison > 0 { + toUpdate.Set(entry.Info.Name, &struct { + isDependency bool + entry *utils.RepositoryEntry + }{isDependency: false, entry: entry}) + } else if reinstall { + toUpdate.Set(entry.Info.Name, &struct { + isDependency bool + entry *utils.RepositoryEntry + }{isDependency: false, entry: entry}) + } } } if toUpdate.Len() == 0 { @@ -445,13 +445,13 @@ func resolveCommand() { if installedInfo == nil { fmt.Printf("%s: %s (Install) %s\n", value.entry.Info.Name, value.entry.Info.GetFullVersion(), sourceInfo) continue - } - - comparison := utils.ComparePackageVersions(*value.entry.Info, *installedInfo) - if comparison > 0 { - fmt.Printf("%s: %s -> %s (Upgrade) %s\n", value.entry.Info.Name, installedInfo.GetFullVersion(), value.entry.Info.GetFullVersion(), sourceInfo) - } else if reinstall { - fmt.Printf("%s: %s -> %s (Reinstall) %s\n", value.entry.Info.Name, installedInfo.GetFullVersion(), value.entry.Info.GetFullVersion(), sourceInfo) + } else { + comparison := utils.ComparePackageVersions(*value.entry.Info, *installedInfo) + if comparison > 0 { + fmt.Printf("%s: %s -> %s (Upgrade) %s\n", value.entry.Info.Name, installedInfo.GetFullVersion(), value.entry.Info.GetFullVersion(), sourceInfo) + } else if reinstall { + fmt.Printf("%s: %s -> %s (Reinstall) %s\n", value.entry.Info.Name, installedInfo.GetFullVersion(), value.entry.Info.GetFullVersion(), sourceInfo) + } } } From c8939614b1bf6e4fd51e07d74eeaf46aadc44d16 Mon Sep 17 00:00:00 2001 From: EnumDev Date: Tue, 8 Oct 2024 19:59:29 +0300 Subject: [PATCH 5/5] Fixed circular dependency problems --- main.go | 4 ++-- utils/package_utils.go | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/main.go b/main.go index e042b5e..739dd31 100644 --- a/main.go +++ b/main.go @@ -224,7 +224,7 @@ func resolveCommand() { }]() for _, pkg := range clone.Keys() { value, _ := clone.Get(pkg) - resolved, unresolved := value.pkgInfo.ResolveAll(&[]string{}, &[]string{}, value.pkgInfo.Type == "source", !noOptional, !reinstall, rootDir) + resolved, unresolved := value.pkgInfo.ResolveAll(&[]string{}, &[]string{}, value.pkgInfo.Type == "source", !noOptional, !reinstall, verbose, rootDir) unresolvedDepends = append(unresolvedDepends, unresolved...) for _, depend := range resolved { if _, ok := pkgsToInstall.Get(depend); !ok && depend != value.pkgInfo.Name { @@ -411,7 +411,7 @@ func resolveCommand() { clone := toUpdate.Copy() for _, key := range clone.Keys() { pkg, _ := clone.Get(key) - r, u := pkg.entry.Info.ResolveAll(&[]string{}, &[]string{}, pkg.entry.Info.Type == "source", !noOptional, true, rootDir) + r, u := pkg.entry.Info.ResolveAll(&[]string{}, &[]string{}, pkg.entry.Info.Type == "source", !noOptional, true, verbose, rootDir) unresolved = append(unresolved, u...) for _, depend := range r { if _, ok := toUpdate.Get(depend); !ok { diff --git a/utils/package_utils.go b/utils/package_utils.go index b550fe7..04b4435 100644 --- a/utils/package_utils.go +++ b/utils/package_utils.go @@ -1284,11 +1284,21 @@ func (pkgInfo *PackageInfo) CheckConflicts(rootDir string) []string { return ret } -func (pkgInfo *PackageInfo) ResolveAll(resolved, unresolved *[]string, checkMake, checkOptional, ignoreInstalled bool, rootDir string) ([]string, []string) { +func (pkgInfo *PackageInfo) ResolveAll(resolved, unresolved *[]string, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) ([]string, []string) { *unresolved = append(*unresolved, pkgInfo.Name) for _, depend := range pkgInfo.GetAllDependencies(checkMake, checkOptional) { + depend = strings.TrimSpace(depend) + depend = strings.ToLower(depend) if !slices.Contains(*resolved, depend) { - if slices.Contains(*unresolved, depend) || (ignoreInstalled && IsPackageInstalled(depend, rootDir)) { + if slices.Contains(*unresolved, depend) { + if verbose { + fmt.Printf("Circular dependency was detected (%s -> %s). Installing %s first\n", pkgInfo.Name, depend, depend) + } + if !slices.Contains(*resolved, depend) { + *resolved = append(*resolved, depend) + } + continue + } else if ignoreInstalled && IsPackageInstalled(depend, rootDir) { continue } entry, _, err := GetRepositoryEntry(depend) @@ -1298,7 +1308,7 @@ func (pkgInfo *PackageInfo) ResolveAll(resolved, unresolved *[]string, checkMake } continue } - entry.Info.ResolveAll(resolved, unresolved, checkMake, checkOptional, ignoreInstalled, rootDir) + entry.Info.ResolveAll(resolved, unresolved, checkMake, checkOptional, ignoreInstalled, verbose, rootDir) } } if !slices.Contains(*resolved, pkgInfo.Name) {