fix(sync): prefer repository replacements over matching AUR upgrades (#2910)
fix upgrade handling for repo replacements
This commit is contained in:
1 parent
9e47f9496d
commit
32a4c9466d
6 files changed
+122
-8
No files matched your search
@@ -54,6 +54,7 @@ type Executor interface {
|
||||
PackageGroups(IPackage) []string
|
||||
PackageOptionalDepends(IPackage) []Depend
|
||||
PackageProvides(IPackage) []Depend
|
||||
PackageReplaces(IPackage) []Depend
|
||||
PackagesFromGroup(string) []IPackage
|
||||
PackagesFromGroupAndDB(string, string) ([]IPackage, error)
|
||||
RefreshHandle() error
|
||||
|
||||
@@ -415,6 +415,14 @@ func (ae *AlpmExecutor) PackageProvides(pkg alpm.Package) []alpm.Depend {
|
||||
return pkg.Provides()
|
||||
}
|
||||
|
||||
func (ae *AlpmExecutor) PackageReplaces(pkg alpm.Package) []alpm.Depend {
|
||||
if pkgWithReplaces, ok := pkg.(interface{ Replaces() []alpm.Depend }); ok {
|
||||
return pkgWithReplaces.Replaces()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ae *AlpmExecutor) PackageGroups(pkg alpm.Package) []string {
|
||||
return pkg.Groups()
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ type DBExecutor struct {
|
||||
PackageDependsFn func(IPackage) []Depend
|
||||
PackageOptionalDependsFn func(alpm.Package) []alpm.Depend
|
||||
PackageProvidesFn func(IPackage) []Depend
|
||||
PackageReplacesFn func(IPackage) []Depend
|
||||
PackagesFromGroupFn func(string) []IPackage
|
||||
PackagesFromGroupAndDBFn func(string, string) ([]IPackage, error)
|
||||
RefreshHandleFn func() error
|
||||
@@ -134,6 +135,17 @@ func (t *DBExecutor) PackageProvides(iPackage IPackage) []Depend {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (t *DBExecutor) PackageReplaces(iPackage IPackage) []Depend {
|
||||
if t.PackageReplacesFn != nil {
|
||||
return t.PackageReplacesFn(iPackage)
|
||||
}
|
||||
if pkg, ok := iPackage.(interface{ Replaces() []alpm.Depend }); ok {
|
||||
return pkg.Replaces()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *DBExecutor) PackagesFromGroup(s string) []IPackage {
|
||||
if t.PackagesFromGroupFn != nil {
|
||||
return t.PackagesFromGroupFn(s)
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@ type Package struct {
|
||||
PReason alpm.PkgReason
|
||||
PDepends DependList
|
||||
PProvides DependList
|
||||
PReplaces DependList
|
||||
PArchitecture string
|
||||
}
|
||||
|
||||
@@ -164,7 +165,7 @@ func (p *Package) Origin() alpm.PkgFrom {
|
||||
|
||||
// Replaces returns a DependList with the packages this package replaces.
|
||||
func (p *Package) Replaces() []alpm.Depend {
|
||||
panic("not implemented")
|
||||
return p.PReplaces.Depends
|
||||
}
|
||||
|
||||
// URL returns the upstream URL of the package.
|
||||
|
||||
+35
-7
@@ -64,15 +64,35 @@ func (u *UpgradeService) upGraph(ctx context.Context, graph *topo.Graph[string,
|
||||
filter Filter,
|
||||
) (err error) {
|
||||
var (
|
||||
develUp UpSlice
|
||||
errs []error
|
||||
aurdata = make(map[string]*aur.Pkg)
|
||||
aurUp UpSlice
|
||||
develUp UpSlice
|
||||
errs []error
|
||||
aurdata = make(map[string]*aur.Pkg)
|
||||
aurUp UpSlice
|
||||
syncUpgrades map[string]db.SyncUpgrade
|
||||
)
|
||||
|
||||
remote := u.dbExecutor.InstalledRemotePackages()
|
||||
remoteNames := u.dbExecutor.InstalledRemotePackageNames()
|
||||
|
||||
if u.cfg.Mode.AtLeastRepo() {
|
||||
syncUpgrades, err = u.dbExecutor.SyncUpgrades(enableDowngrade)
|
||||
errs = append(errs, err)
|
||||
|
||||
replaced := u.syncReplacedPackageNames(syncUpgrades)
|
||||
if replaced.Cardinality() > 0 {
|
||||
filteredRemote := make(map[string]db.IPackage, len(remote))
|
||||
for name, pkg := range remote {
|
||||
if !replaced.Contains(name) {
|
||||
filteredRemote[name] = pkg
|
||||
}
|
||||
}
|
||||
remote = filteredRemote
|
||||
remoteNames = slices.DeleteFunc(slices.Clone(remoteNames), func(name string) bool {
|
||||
return replaced.Contains(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if u.cfg.Mode.AtLeastAUR() {
|
||||
u.log.OperationInfoln(gotext.Get("Searching AUR for updates..."))
|
||||
|
||||
@@ -168,7 +188,6 @@ func (u *UpgradeService) upGraph(ctx context.Context, graph *topo.Graph[string,
|
||||
if u.cfg.Mode.AtLeastRepo() {
|
||||
u.log.OperationInfoln(gotext.Get("Searching databases for updates..."))
|
||||
|
||||
syncUpgrades, err := u.dbExecutor.SyncUpgrades(enableDowngrade)
|
||||
for _, up := range syncUpgrades {
|
||||
if filter != nil && !filter(&db.Upgrade{
|
||||
Name: up.Package.Name(),
|
||||
@@ -184,13 +203,22 @@ func (u *UpgradeService) upGraph(ctx context.Context, graph *topo.Graph[string,
|
||||
upgradeInfo := up
|
||||
graph = u.grapher.GraphSyncPkg(ctx, graph, up.Package, &upgradeInfo)
|
||||
}
|
||||
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (u *UpgradeService) syncReplacedPackageNames(syncUpgrades map[string]db.SyncUpgrade) mapset.Set[string] {
|
||||
replaced := mapset.NewThreadUnsafeSet[string]()
|
||||
for _, up := range syncUpgrades {
|
||||
for _, replacement := range u.dbExecutor.PackageReplaces(up.Package) {
|
||||
replaced.Add(replacement.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return replaced
|
||||
}
|
||||
|
||||
func (u *UpgradeService) graphToUpSlice(graph *topo.Graph[string, *dep.InstallInfo]) (aurUp, repoUp UpSlice) {
|
||||
aurUp = UpSlice{Up: make([]Upgrade, 0, graph.Len())}
|
||||
repoUp = UpSlice{Up: make([]Upgrade, 0, graph.Len()), Repos: u.dbExecutor.Repos()}
|
||||
|
||||
@@ -759,6 +759,70 @@ func TestUpgradeService_GraphUpgradesNoUpdates(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpgradeService_GraphUpgradesPrefersSyncReplacementOverAUR(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
coreDB := mock.NewDB("extra")
|
||||
dbExe := &mock.DBExecutor{
|
||||
InstalledRemotePackageNamesFn: func() []string {
|
||||
return []string{"sdl2"}
|
||||
},
|
||||
InstalledRemotePackagesFn: func() map[string]mock.IPackage {
|
||||
return map[string]mock.IPackage{
|
||||
"sdl2": &mock.Package{
|
||||
PName: "sdl2",
|
||||
PBase: "sdl2",
|
||||
PVersion: "2.30.11-1",
|
||||
PReason: alpm.PkgReasonDepend,
|
||||
},
|
||||
}
|
||||
},
|
||||
SyncUpgradesFn: func(bool) (map[string]db.SyncUpgrade, error) {
|
||||
return map[string]db.SyncUpgrade{
|
||||
"sdl2-compat": {
|
||||
Package: &mock.Package{
|
||||
PName: "sdl2-compat",
|
||||
PVersion: "2.32.50-1",
|
||||
PReason: alpm.PkgReasonDepend,
|
||||
PDB: coreDB,
|
||||
PReplaces: mock.DependList{Depends: []alpm.Depend{
|
||||
{Name: "sdl2"},
|
||||
}},
|
||||
},
|
||||
LocalVersion: "-",
|
||||
Reason: alpm.PkgReasonDepend,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
ReposFn: func() []string { return []string{"extra"} },
|
||||
}
|
||||
|
||||
mockAUR := &mockaur.MockAUR{
|
||||
GetFn: func(_ context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
assert.Empty(t, query.Needles)
|
||||
return []aur.Pkg{}, nil
|
||||
},
|
||||
}
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
grapher := dep.NewGrapher(dbExe, mockAUR, false, true, false, false, false, logger)
|
||||
service := &UpgradeService{
|
||||
log: logger,
|
||||
grapher: grapher,
|
||||
aurCache: mockAUR,
|
||||
dbExecutor: dbExe,
|
||||
vcsStore: &vcs.Mock{},
|
||||
cfg: &settings.Configuration{Mode: parser.ModeAny},
|
||||
AURWarnings: query.NewWarnings(logger),
|
||||
}
|
||||
|
||||
graph, err := service.GraphUpgrades(t.Context(), nil, false, func(*Upgrade) bool { return true })
|
||||
require.NoError(t, err)
|
||||
assert.False(t, graph.Exists("sdl2"))
|
||||
require.True(t, graph.Exists("sdl2-compat"))
|
||||
assert.Equal(t, dep.Sync, graph.GetNodeInfo("sdl2-compat").Value.Source)
|
||||
}
|
||||
|
||||
func TestUpgradeService_UserExcludeUpgradesWithoutLuaHookUsesNativeMenu(t *testing.T) {
|
||||
t.Parallel()
|
||||
graph := newUpgradeSelectTestGraph(t)
|
||||
|
||||
Reference in new issue
Block a user