From 87c492a30c58df7393a675fdc613f6de5259f01c Mon Sep 17 00:00:00 2001 From: EnumDev Date: Fri, 4 Apr 2025 21:40:21 +0300 Subject: [PATCH] Improve virtual package handling --- main.go | 28 ++++++++++++++---- utils/config.go | 1 + utils/package_utils.go | 34 ++++++++++++++++++---- utils/repo_utils.go | 64 ++++++++++++++++++------------------------ 4 files changed, 80 insertions(+), 47 deletions(-) diff --git a/main.go b/main.go index a43e2c8..2c115ba 100644 --- a/main.go +++ b/main.go @@ -105,9 +105,13 @@ func resolveCommand() { var info *utils.PackageInfo isFile := false if showRepoInfo { - entry, _, err := utils.GetRepositoryEntry(pkg) + var err error + var entry *utils.RepositoryEntry + entry, _, err = utils.GetRepositoryEntry(pkg) if err != nil { - log.Fatalf("Error: could not find package (%s) in any repository\n", pkg) + if entry = utils.ResolveVirtualPackage(pkg); entry == nil { + log.Fatalf("Error: could not find package (%s) in any repository\n", pkg) + } } info = entry.Info } else if stat, err := os.Stat(pkg); err == nil && !stat.IsDir() { @@ -118,7 +122,11 @@ func resolveCommand() { info = bpmpkg.PkgInfo isFile = true } else { - info = utils.GetPackageInfo(pkg, rootDir) + if isVirtual, p := utils.IsVirtualPackage(pkg, rootDir); isVirtual { + info = utils.GetPackageInfo(p, rootDir) + } else { + info = utils.GetPackageInfo(pkg, rootDir) + } } if info == nil { log.Fatalf("Error: package (%s) is not installed\n", pkg) @@ -236,8 +244,18 @@ func resolveCommand() { BpmPackage: bpmpkg, }) } else { - entry, _, err := utils.GetRepositoryEntry(pkg) - if err != nil { + var entry *utils.RepositoryEntry + + if e, _, err := utils.GetRepositoryEntry(pkg); err == nil { + entry = e + } else if isVirtual, p := utils.IsVirtualPackage(pkg, rootDir); isVirtual { + entry, _, err = utils.GetRepositoryEntry(p) + if err != nil { + log.Fatalf("Error: could not find package (%s) in any repository\n", p) + } + } else if e := utils.ResolveVirtualPackage(pkg); e != nil { + entry = e + } else { log.Fatalf("Error: could not find package (%s) in any repository\n", pkg) } if !reinstall && utils.IsPackageInstalled(entry.Info.Name, rootDir) && utils.GetPackageInfo(entry.Info.Name, rootDir).GetFullVersion() == entry.Info.GetFullVersion() { diff --git a/utils/config.go b/utils/config.go index 037373b..e57b03f 100644 --- a/utils/config.go +++ b/utils/config.go @@ -42,6 +42,7 @@ func ReadConfig() { } for _, repo := range BPMConfig.Repositories { repo.Entries = make(map[string]*RepositoryEntry) + repo.VirtualPackages = make(map[string][]string) err := repo.ReadLocalDatabase() if err != nil { log.Fatal(err) diff --git a/utils/package_utils.go b/utils/package_utils.go index a0d2aeb..443f981 100644 --- a/utils/package_utils.go +++ b/utils/package_utils.go @@ -1340,15 +1340,19 @@ func (pkgInfo *PackageInfo) ResolveDependencies(resolved, unresolved *[]string, *resolved = append(*resolved, depend) } continue - } else if ignoreInstalled && IsPackageInstalled(depend, rootDir) { + } else if ignoreInstalled && IsPackageProvided(depend, rootDir) { continue } - entry, _, err := GetRepositoryEntry(depend) + var err error + var entry *RepositoryEntry + entry, _, err = GetRepositoryEntry(depend) if err != nil { - if !slices.Contains(*unresolved, depend) { - *unresolved = append(*unresolved, depend) + if entry = ResolveVirtualPackage(depend); entry == nil { + if !slices.Contains(*unresolved, depend) { + *unresolved = append(*unresolved, depend) + } + continue } - continue } entry.Info.ResolveDependencies(resolved, unresolved, checkMake, checkOptional, ignoreInstalled, verbose, rootDir) } @@ -1369,6 +1373,26 @@ func IsPackageInstalled(pkg, rootDir string) bool { return true } +func IsVirtualPackage(pkg, rootDir string) (bool, string) { + pkgs, err := GetInstalledPackages(rootDir) + if err != nil { + return false, "" + } + for _, p := range pkgs { + if p == pkg { + return false, "" + } + i := GetPackageInfo(p, rootDir) + if i == nil { + continue + } + if slices.Contains(i.Provides, pkg) { + return true, p + } + } + return false, "" +} + func IsPackageProvided(pkg, rootDir string) bool { pkgs, err := GetInstalledPackages(rootDir) if err != nil { diff --git a/utils/repo_utils.go b/utils/repo_utils.go index 4ea31ac..0cf8c1f 100644 --- a/utils/repo_utils.go +++ b/utils/repo_utils.go @@ -8,24 +8,23 @@ import ( "net/url" "os" "path" - "sort" "strings" ) type Repository struct { - Name string `yaml:"name"` - Source string `yaml:"source"` - Disabled *bool `yaml:"disabled"` - Entries map[string]*RepositoryEntry + Name string `yaml:"name"` + Source string `yaml:"source"` + Disabled *bool `yaml:"disabled"` + Entries map[string]*RepositoryEntry + VirtualPackages map[string][]string } type RepositoryEntry struct { - Info *PackageInfo `yaml:"info"` - Download string `yaml:"download"` - DownloadSize uint64 `yaml:"download_size"` - InstalledSize uint64 `yaml:"installed_size"` - IsVirtualPackage bool `yaml:"-"` - Repository *Repository + Info *PackageInfo `yaml:"info"` + Download string `yaml:"download"` + DownloadSize uint64 `yaml:"download_size"` + InstalledSize uint64 `yaml:"installed_size"` + Repository *Repository } func (repo *Repository) ContainsPackage(pkg string) bool { @@ -44,8 +43,6 @@ func (repo *Repository) ReadLocalDatabase() error { return err } - virtualPackages := make(map[string][]string) - data := string(bytes) for _, b := range strings.Split(data, "---") { entry := RepositoryEntry{ @@ -65,11 +62,10 @@ func (repo *Repository) ReadLocalDatabase() error { Conflicts: make([]string, 0), Provides: make([]string, 0), }, - Download: "", - DownloadSize: 0, - InstalledSize: 0, - IsVirtualPackage: false, - Repository: repo, + Download: "", + DownloadSize: 0, + InstalledSize: 0, + Repository: repo, } err := yaml.Unmarshal([]byte(b), &entry) if err != nil { @@ -77,26 +73,11 @@ func (repo *Repository) ReadLocalDatabase() error { } for _, p := range entry.Info.Provides { - virtualPackages[p] = append(virtualPackages[p], entry.Info.Name) + repo.VirtualPackages[p] = append(repo.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, - DownloadSize: repo.Entries[value[0]].DownloadSize, - InstalledSize: repo.Entries[value[0]].InstalledSize, - IsVirtualPackage: true, - Repository: repo, - } - repo.Entries[key] = &entry - } return nil } @@ -170,9 +151,6 @@ func GetRepositoryEntry(str string) (*RepositoryEntry, *Repository, error) { func FindReplacement(pkg string) *RepositoryEntry { for _, repo := range BPMConfig.Repositories { for _, entry := range repo.Entries { - if entry.IsVirtualPackage { - continue - } for _, replaced := range entry.Info.Replaces { if replaced == pkg { return entry @@ -184,6 +162,18 @@ func FindReplacement(pkg string) *RepositoryEntry { return nil } +func ResolveVirtualPackage(vpkg string) *RepositoryEntry { + for _, repo := range BPMConfig.Repositories { + if v, ok := repo.VirtualPackages[vpkg]; ok { + for _, pkg := range v { + return repo.Entries[pkg] + } + } + } + + return nil +} + func (repo *Repository) FetchPackage(pkg string) (string, error) { if !repo.ContainsPackage(pkg) { return "", errors.New("could not fetch package '" + pkg + "'")