From 4143a23c91c892ed846ef4537a65c9907ce2449d Mon Sep 17 00:00:00 2001 From: AI Bot Date: Fri, 17 Apr 2026 18:24:14 +0200 Subject: [PATCH] Implement package resolve logic fixes --- .../changes/fix-package-fetch-logic/tasks.md | 10 +-- pkg/fetch/fetch.go | 83 +++++++++---------- pkg/pacman/pacman.go | 4 +- 3 files changed, 48 insertions(+), 49 deletions(-) diff --git a/openspec/changes/fix-package-fetch-logic/tasks.md b/openspec/changes/fix-package-fetch-logic/tasks.md index 0fbd183..9c15034 100644 --- a/openspec/changes/fix-package-fetch-logic/tasks.md +++ b/openspec/changes/fix-package-fetch-logic/tasks.md @@ -1,7 +1,7 @@ ## 1. Fix Resolve Function Logic -- [ ] 1.1 Change initialization: start packages with Exists: false instead of true -- [ ] 1.2 Reorder to check sync DBs BEFORE local DB -- [ ] 1.3 Separate availability check (sync DBs) from installation check (local DB) -- [ ] 1.4 Add AUR fallback for packages not in sync DBs -- [ ] 1.5 Validate all packages have either Exists or InAUR before returning +- [x] 1.1 Change initialization: start packages with Exists: false instead of true +- [x] 1.2 Reorder to check sync DBs BEFORE local DB +- [x] 1.3 Separate availability check (sync DBs) from installation check (local DB) +- [x] 1.4 Add AUR fallback for packages not in sync DBs +- [x] 1.5 Validate all packages have either Exists or InAUR before returning diff --git a/pkg/fetch/fetch.go b/pkg/fetch/fetch.go index 07ecbac..54fcddf 100644 --- a/pkg/fetch/fetch.go +++ b/pkg/fetch/fetch.go @@ -189,7 +189,19 @@ func (f *Fetcher) Resolve(packages []string) (map[string]*PackageInfo, error) { result := make(map[string]*PackageInfo) for _, pkg := range packages { - result[pkg] = &PackageInfo{Name: pkg, Exists: true} + result[pkg] = &PackageInfo{Name: pkg, Exists: false} + } + + syncPkgs, err := f.checkSyncDBs(packages) + if err != nil { + return nil, err + } + fmt.Fprintf(os.Stderr, "[debug] Resolve: sync db check done (%.2fs)\n", time.Since(start).Seconds()) + + for pkg, syncPkg := range syncPkgs { + result[pkg].Exists = true + result[pkg].InAUR = false + result[pkg].syncPkg = syncPkg } localPkgs, err := f.buildLocalPkgMap() @@ -198,53 +210,30 @@ func (f *Fetcher) Resolve(packages []string) (map[string]*PackageInfo, error) { } fmt.Fprintf(os.Stderr, "[debug] Resolve: local pkgs built (%.2fs)\n", time.Since(start).Seconds()) - var notInLocal []string - for _, pkg := range packages { - if localPkg, ok := localPkgs[pkg]; ok { - result[pkg] = &PackageInfo{ - Name: pkg, - Exists: true, - InAUR: false, - Installed: true, - syncPkg: localPkg, - } - } else { - notInLocal = append(notInLocal, pkg) + for pkg := range localPkgs { + if info, ok := result[pkg]; ok { + info.Installed = true } } - if len(notInLocal) > 0 { - syncPkgs, err := f.checkSyncDBs(notInLocal) - if err != nil { - return nil, err + var notInSync []string + for _, pkg := range packages { + if !result[pkg].Exists { + notInSync = append(notInSync, pkg) } + } - f.ensureAURCache(packages) + if len(notInSync) > 0 { + f.ensureAURCache(notInSync) for _, pkg := range packages { info := result[pkg] - if info == nil { - continue - } - - if info.Installed { - if aurInfo, ok := f.aurCache[pkg]; ok { - info.InAUR = true - info.AURInfo = &aurInfo - } - continue - } - - if syncPkg, ok := syncPkgs[pkg]; ok { - info.InAUR = false - info.Installed = false - info.syncPkg = syncPkg + if info.Exists { continue } if aurInfo, ok := f.aurCache[pkg]; ok { info.InAUR = true - info.Installed = false info.AURInfo = &aurInfo continue } @@ -253,6 +242,13 @@ func (f *Fetcher) Resolve(packages []string) (map[string]*PackageInfo, error) { } } + for _, pkg := range packages { + info := result[pkg] + if !info.Exists && !info.InAUR { + return nil, fmt.Errorf("package not validated: %s", pkg) + } + } + fmt.Fprintf(os.Stderr, "[debug] Resolve: done (%.2fs)\n", time.Since(start).Seconds()) return result, nil } @@ -277,18 +273,21 @@ func (f *Fetcher) ensureAURCache(packages []string) { return } - f.fetchAURInfo(uncached) + _, err := f.fetchAURInfo(uncached) + if err != nil { + fmt.Fprintf(os.Stderr, "[debug] ensureAURCache: fetch error: %v\n", err) + } fmt.Fprintf(os.Stderr, "[debug] ensureAURCache: done (%.2fs)\n", time.Since(start).Seconds()) } -func (f *Fetcher) fetchAURInfo(packages []string) map[string]AURPackage { +func (f *Fetcher) fetchAURInfo(packages []string) (map[string]AURPackage, error) { start := time.Now() fmt.Fprintf(os.Stderr, "[debug] fetchAURInfo: starting...\n") result := make(map[string]AURPackage) if len(packages) == 0 { - return result + return result, nil } v := url.Values{} @@ -298,18 +297,18 @@ func (f *Fetcher) fetchAURInfo(packages []string) map[string]AURPackage { resp, err := http.Get(AURInfoURL + "&" + v.Encode()) if err != nil { - return result + return result, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { - return result + return result, err } var aurResp AURResponse if err := json.Unmarshal(body, &aurResp); err != nil { - return result + return result, err } for _, r := range aurResp.Results { @@ -318,7 +317,7 @@ func (f *Fetcher) fetchAURInfo(packages []string) map[string]AURPackage { } fmt.Fprintf(os.Stderr, "[debug] fetchAURInfo: done (%.2fs)\n", time.Since(start).Seconds()) - return result + return result, nil } func (f *Fetcher) ListOrphans() ([]string, error) { diff --git a/pkg/pacman/pacman.go b/pkg/pacman/pacman.go index d106c79..e7992a0 100644 --- a/pkg/pacman/pacman.go +++ b/pkg/pacman/pacman.go @@ -137,7 +137,7 @@ func categorizePackages(f *fetch.Fetcher, packages []string) (pacmanPkgs, aurPkg for _, pkg := range packages { info := resolved[pkg] - if info == nil || !info.Exists { + if info == nil || (!info.Exists && !info.InAUR) { fmt.Fprintf(os.Stderr, "error: package not found: %s\n", pkg) continue } @@ -335,7 +335,7 @@ func DryRun(packages []string) (*output.Result, error) { var aurPkgs []string for _, pkg := range packages { info := resolved[pkg] - if info == nil || !info.Exists { + if info == nil || (!info.Exists && !info.InAUR) { return nil, fmt.Errorf("package not found: %s", pkg) } if info.InAUR {