mirror of
https://github.com/mudler/luet.git
synced 2025-09-04 00:34:41 +00:00
Add to the Solver the capability to check conflicts with revdeps
This commit is contained in:
@@ -31,6 +31,8 @@ type PackageSolver interface {
|
|||||||
Uninstall(candidate pkg.Package, checkconflicts bool) (pkg.Packages, error)
|
Uninstall(candidate pkg.Package, checkconflicts bool) (pkg.Packages, error)
|
||||||
ConflictsWithInstalled(p pkg.Package) (bool, error)
|
ConflictsWithInstalled(p pkg.Package) (bool, error)
|
||||||
ConflictsWith(p pkg.Package, ls pkg.Packages) (bool, error)
|
ConflictsWith(p pkg.Package, ls pkg.Packages) (bool, error)
|
||||||
|
Conflicts(pack pkg.Package, lsp pkg.Packages) (bool, error)
|
||||||
|
|
||||||
World() pkg.Packages
|
World() pkg.Packages
|
||||||
Upgrade(checkconflicts bool) (pkg.Packages, PackagesAssertions, error)
|
Upgrade(checkconflicts bool) (pkg.Packages, PackagesAssertions, error)
|
||||||
|
|
||||||
@@ -149,6 +151,35 @@ func (s *Solver) getList(db pkg.PackageDatabase, lsp pkg.Packages) (pkg.Packages
|
|||||||
return ls, nil
|
return ls, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Conflicts acts like ConflictsWith, but uses package's reverse dependencies to
|
||||||
|
// determine if it conflicts with the given set
|
||||||
|
func (s *Solver) Conflicts(pack pkg.Package, lsp pkg.Packages) (bool, error) {
|
||||||
|
p, err := s.DefinitionDatabase.FindPackage(pack)
|
||||||
|
if err != nil {
|
||||||
|
p = pack
|
||||||
|
}
|
||||||
|
|
||||||
|
ls, err := s.getList(s.DefinitionDatabase, lsp)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrap(err, "Package not found in definition db")
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.noRulesWorld() {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
temporarySet := pkg.NewInMemoryDatabase(false)
|
||||||
|
for _, p := range ls {
|
||||||
|
temporarySet.CreatePackage(p)
|
||||||
|
}
|
||||||
|
visited := make(map[string]interface{})
|
||||||
|
revdeps := p.ExpandedRevdeps(temporarySet, visited)
|
||||||
|
|
||||||
|
return len(revdeps) != 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConflictsWith return true if a package is part of the requirement set of a list of package
|
||||||
|
// return false otherwise (and thus it is NOT relevant to the given list)
|
||||||
func (s *Solver) ConflictsWith(pack pkg.Package, lsp pkg.Packages) (bool, error) {
|
func (s *Solver) ConflictsWith(pack pkg.Package, lsp pkg.Packages) (bool, error) {
|
||||||
p, err := s.DefinitionDatabase.FindPackage(pack)
|
p, err := s.DefinitionDatabase.FindPackage(pack)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -672,6 +672,99 @@ var _ = Describe("Solver", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(val).ToNot(BeTrue())
|
Expect(val).ToNot(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("Find conflicts using revdeps", func() {
|
||||||
|
|
||||||
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := s.Conflicts(A, dbInstalled.World())
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(val).To(BeTrue())
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Find nested conflicts with revdeps", func() {
|
||||||
|
|
||||||
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := s.Conflicts(D, dbInstalled.World())
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(val).To(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Doesn't find nested conflicts with revdeps", func() {
|
||||||
|
|
||||||
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := s.Conflicts(C, dbInstalled.World())
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(val).ToNot(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Doesn't find conflicts with revdeps", func() {
|
||||||
|
|
||||||
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
val, err := s.Conflicts(C, dbInstalled.World())
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(val).ToNot(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
It("Uninstalls simple packages not in world correctly", func() {
|
It("Uninstalls simple packages not in world correctly", func() {
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
Reference in New Issue
Block a user