Skip to content

Commit 32a4c94

Browse files
fix(sync): prefer repository replacements over matching AUR upgrades (#2910)
fix upgrade handling for repo replacements
1 parent 9e47f94 commit 32a4c94

6 files changed

Lines changed: 122 additions & 8 deletions

File tree

pkg/db/executor.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type Executor interface {
5454
PackageGroups(IPackage) []string
5555
PackageOptionalDepends(IPackage) []Depend
5656
PackageProvides(IPackage) []Depend
57+
PackageReplaces(IPackage) []Depend
5758
PackagesFromGroup(string) []IPackage
5859
PackagesFromGroupAndDB(string, string) ([]IPackage, error)
5960
RefreshHandle() error

pkg/db/ialpm/alpm.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,14 @@ func (ae *AlpmExecutor) PackageProvides(pkg alpm.Package) []alpm.Depend {
415415
return pkg.Provides()
416416
}
417417

418+
func (ae *AlpmExecutor) PackageReplaces(pkg alpm.Package) []alpm.Depend {
419+
if pkgWithReplaces, ok := pkg.(interface{ Replaces() []alpm.Depend }); ok {
420+
return pkgWithReplaces.Replaces()
421+
}
422+
423+
return nil
424+
}
425+
418426
func (ae *AlpmExecutor) PackageGroups(pkg alpm.Package) []string {
419427
return pkg.Groups()
420428
}

pkg/db/mock/executor.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type DBExecutor struct {
2727
PackageDependsFn func(IPackage) []Depend
2828
PackageOptionalDependsFn func(alpm.Package) []alpm.Depend
2929
PackageProvidesFn func(IPackage) []Depend
30+
PackageReplacesFn func(IPackage) []Depend
3031
PackagesFromGroupFn func(string) []IPackage
3132
PackagesFromGroupAndDBFn func(string, string) ([]IPackage, error)
3233
RefreshHandleFn func() error
@@ -134,6 +135,17 @@ func (t *DBExecutor) PackageProvides(iPackage IPackage) []Depend {
134135
panic("implement me")
135136
}
136137

138+
func (t *DBExecutor) PackageReplaces(iPackage IPackage) []Depend {
139+
if t.PackageReplacesFn != nil {
140+
return t.PackageReplacesFn(iPackage)
141+
}
142+
if pkg, ok := iPackage.(interface{ Replaces() []alpm.Depend }); ok {
143+
return pkg.Replaces()
144+
}
145+
146+
return nil
147+
}
148+
137149
func (t *DBExecutor) PackagesFromGroup(s string) []IPackage {
138150
if t.PackagesFromGroupFn != nil {
139151
return t.PackagesFromGroupFn(s)

pkg/db/mock/repo.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type Package struct {
2525
PReason alpm.PkgReason
2626
PDepends DependList
2727
PProvides DependList
28+
PReplaces DependList
2829
PArchitecture string
2930
}
3031

@@ -164,7 +165,7 @@ func (p *Package) Origin() alpm.PkgFrom {
164165

165166
// Replaces returns a DependList with the packages this package replaces.
166167
func (p *Package) Replaces() []alpm.Depend {
167-
panic("not implemented")
168+
return p.PReplaces.Depends
168169
}
169170

170171
// URL returns the upstream URL of the package.

pkg/upgrade/service.go

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,35 @@ func (u *UpgradeService) upGraph(ctx context.Context, graph *topo.Graph[string,
6464
filter Filter,
6565
) (err error) {
6666
var (
67-
develUp UpSlice
68-
errs []error
69-
aurdata = make(map[string]*aur.Pkg)
70-
aurUp UpSlice
67+
develUp UpSlice
68+
errs []error
69+
aurdata = make(map[string]*aur.Pkg)
70+
aurUp UpSlice
71+
syncUpgrades map[string]db.SyncUpgrade
7172
)
7273

7374
remote := u.dbExecutor.InstalledRemotePackages()
7475
remoteNames := u.dbExecutor.InstalledRemotePackageNames()
7576

77+
if u.cfg.Mode.AtLeastRepo() {
78+
syncUpgrades, err = u.dbExecutor.SyncUpgrades(enableDowngrade)
79+
errs = append(errs, err)
80+
81+
replaced := u.syncReplacedPackageNames(syncUpgrades)
82+
if replaced.Cardinality() > 0 {
83+
filteredRemote := make(map[string]db.IPackage, len(remote))
84+
for name, pkg := range remote {
85+
if !replaced.Contains(name) {
86+
filteredRemote[name] = pkg
87+
}
88+
}
89+
remote = filteredRemote
90+
remoteNames = slices.DeleteFunc(slices.Clone(remoteNames), func(name string) bool {
91+
return replaced.Contains(name)
92+
})
93+
}
94+
}
95+
7696
if u.cfg.Mode.AtLeastAUR() {
7797
u.log.OperationInfoln(gotext.Get("Searching AUR for updates..."))
7898

@@ -168,7 +188,6 @@ func (u *UpgradeService) upGraph(ctx context.Context, graph *topo.Graph[string,
168188
if u.cfg.Mode.AtLeastRepo() {
169189
u.log.OperationInfoln(gotext.Get("Searching databases for updates..."))
170190

171-
syncUpgrades, err := u.dbExecutor.SyncUpgrades(enableDowngrade)
172191
for _, up := range syncUpgrades {
173192
if filter != nil && !filter(&db.Upgrade{
174193
Name: up.Package.Name(),
@@ -184,13 +203,22 @@ func (u *UpgradeService) upGraph(ctx context.Context, graph *topo.Graph[string,
184203
upgradeInfo := up
185204
graph = u.grapher.GraphSyncPkg(ctx, graph, up.Package, &upgradeInfo)
186205
}
187-
188-
errs = append(errs, err)
189206
}
190207

191208
return errors.Join(errs...)
192209
}
193210

211+
func (u *UpgradeService) syncReplacedPackageNames(syncUpgrades map[string]db.SyncUpgrade) mapset.Set[string] {
212+
replaced := mapset.NewThreadUnsafeSet[string]()
213+
for _, up := range syncUpgrades {
214+
for _, replacement := range u.dbExecutor.PackageReplaces(up.Package) {
215+
replaced.Add(replacement.Name)
216+
}
217+
}
218+
219+
return replaced
220+
}
221+
194222
func (u *UpgradeService) graphToUpSlice(graph *topo.Graph[string, *dep.InstallInfo]) (aurUp, repoUp UpSlice) {
195223
aurUp = UpSlice{Up: make([]Upgrade, 0, graph.Len())}
196224
repoUp = UpSlice{Up: make([]Upgrade, 0, graph.Len()), Repos: u.dbExecutor.Repos()}

pkg/upgrade/service_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,70 @@ func TestUpgradeService_GraphUpgradesNoUpdates(t *testing.T) {
759759
}
760760
}
761761

762+
func TestUpgradeService_GraphUpgradesPrefersSyncReplacementOverAUR(t *testing.T) {
763+
t.Parallel()
764+
765+
coreDB := mock.NewDB("extra")
766+
dbExe := &mock.DBExecutor{
767+
InstalledRemotePackageNamesFn: func() []string {
768+
return []string{"sdl2"}
769+
},
770+
InstalledRemotePackagesFn: func() map[string]mock.IPackage {
771+
return map[string]mock.IPackage{
772+
"sdl2": &mock.Package{
773+
PName: "sdl2",
774+
PBase: "sdl2",
775+
PVersion: "2.30.11-1",
776+
PReason: alpm.PkgReasonDepend,
777+
},
778+
}
779+
},
780+
SyncUpgradesFn: func(bool) (map[string]db.SyncUpgrade, error) {
781+
return map[string]db.SyncUpgrade{
782+
"sdl2-compat": {
783+
Package: &mock.Package{
784+
PName: "sdl2-compat",
785+
PVersion: "2.32.50-1",
786+
PReason: alpm.PkgReasonDepend,
787+
PDB: coreDB,
788+
PReplaces: mock.DependList{Depends: []alpm.Depend{
789+
{Name: "sdl2"},
790+
}},
791+
},
792+
LocalVersion: "-",
793+
Reason: alpm.PkgReasonDepend,
794+
},
795+
}, nil
796+
},
797+
ReposFn: func() []string { return []string{"extra"} },
798+
}
799+
800+
mockAUR := &mockaur.MockAUR{
801+
GetFn: func(_ context.Context, query *aur.Query) ([]aur.Pkg, error) {
802+
assert.Empty(t, query.Needles)
803+
return []aur.Pkg{}, nil
804+
},
805+
}
806+
807+
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
808+
grapher := dep.NewGrapher(dbExe, mockAUR, false, true, false, false, false, logger)
809+
service := &UpgradeService{
810+
log: logger,
811+
grapher: grapher,
812+
aurCache: mockAUR,
813+
dbExecutor: dbExe,
814+
vcsStore: &vcs.Mock{},
815+
cfg: &settings.Configuration{Mode: parser.ModeAny},
816+
AURWarnings: query.NewWarnings(logger),
817+
}
818+
819+
graph, err := service.GraphUpgrades(t.Context(), nil, false, func(*Upgrade) bool { return true })
820+
require.NoError(t, err)
821+
assert.False(t, graph.Exists("sdl2"))
822+
require.True(t, graph.Exists("sdl2-compat"))
823+
assert.Equal(t, dep.Sync, graph.GetNodeInfo("sdl2-compat").Value.Source)
824+
}
825+
762826
func TestUpgradeService_UserExcludeUpgradesWithoutLuaHookUsesNativeMenu(t *testing.T) {
763827
t.Parallel()
764828
graph := newUpgradeSelectTestGraph(t)

0 commit comments

Comments
 (0)