diff --git a/pkg/package/package.go b/pkg/package/package.go index 7163ac2e..ffc6c94b 100644 --- a/pkg/package/package.go +++ b/pkg/package/package.go @@ -47,7 +47,7 @@ type Package interface { Requires([]*DefaultPackage) Package Conflicts([]*DefaultPackage) Package Revdeps(PackageDatabase) Packages - ExpandedRevdeps(definitiondb PackageDatabase) Packages + ExpandedRevdeps(definitiondb PackageDatabase, visited map[string]interface{}) Packages LabelDeps(PackageDatabase, string) Packages GetProvides() []*DefaultPackage @@ -419,20 +419,38 @@ func (p *DefaultPackage) Revdeps(definitiondb PackageDatabase) Packages { // ExpandedRevdeps returns the package reverse dependencies, // matching also selectors in versions (>, <, >=, <=) -func (p *DefaultPackage) ExpandedRevdeps(definitiondb PackageDatabase) Packages { +func (p *DefaultPackage) ExpandedRevdeps(definitiondb PackageDatabase, visited map[string]interface{}) Packages { var versionsInWorld Packages + if _, ok := visited[p.HumanReadableString()]; ok { + return versionsInWorld + } + for _, w := range definitiondb.World() { if w.Matches(p) { continue } - // for _, re := range w.GetRequires() { - if ok, _ := w.RequiresContains(definitiondb, p); ok { - versionsInWorld = append(versionsInWorld, w) - versionsInWorld = append(versionsInWorld, w.ExpandedRevdeps(definitiondb)...) - } - //} - } + match := false + for _, re := range w.GetRequires() { + if re.Matches(p) { + match = true + } + if !match { + } + packages, _ := re.Expand(definitiondb) + for _, pa := range packages { + if pa.Matches(p) { + match = true + } + } + } + + if match { + versionsInWorld = append(versionsInWorld, w) + versionsInWorld = append(versionsInWorld, w.ExpandedRevdeps(definitiondb, visited)...) + visited[w.HumanReadableString()] = true + } + } return versionsInWorld.Unique() } diff --git a/pkg/package/package_test.go b/pkg/package/package_test.go index 1238b3b2..91c0ae43 100644 --- a/pkg/package/package_test.go +++ b/pkg/package/package_test.go @@ -189,7 +189,8 @@ var _ = Describe("Package", func() { _, err := definitions.CreatePackage(p) Expect(err).ToNot(HaveOccurred()) } - lst := a.ExpandedRevdeps(definitions) + visited := make(map[string]interface{}) + lst := a.ExpandedRevdeps(definitions, visited) Expect(lst).To(ContainElement(c)) Expect(lst).To(ContainElement(d)) Expect(lst).To(ContainElement(e)) @@ -210,7 +211,33 @@ var _ = Describe("Package", func() { _, err := definitions.CreatePackage(p) Expect(err).ToNot(HaveOccurred()) } - lst := a.ExpandedRevdeps(definitions) + visited := make(map[string]interface{}) + + lst := a.ExpandedRevdeps(definitions, visited) + Expect(lst).To(ContainElement(b)) + Expect(lst).To(ContainElement(c)) + Expect(lst).To(ContainElement(d)) + Expect(lst).To(ContainElement(e)) + Expect(len(lst)).To(Equal(4)) + }) + }) + + Context("Expandedrevdeps", func() { + a := NewPackage("A", "1.0", []*DefaultPackage{}, []*DefaultPackage{}) + b := NewPackage("B", "1.0", []*DefaultPackage{&DefaultPackage{Name: "A", Version: ">=1.0"}}, []*DefaultPackage{}) + c := NewPackage("C", "1.1", []*DefaultPackage{&DefaultPackage{Name: "B", Version: ">=1.0"}, &DefaultPackage{Name: "A", Version: ">=0"}}, []*DefaultPackage{}) + d := NewPackage("D", "0.1", []*DefaultPackage{&DefaultPackage{Name: "C", Version: ">=1.0"}}, []*DefaultPackage{}) + e := NewPackage("E", "0.1", []*DefaultPackage{&DefaultPackage{Name: "C", Version: ">=1.0"}}, []*DefaultPackage{}) + + It("Computes correctly", func() { + definitions := NewInMemoryDatabase(false) + for _, p := range []Package{a, b, c, d, e} { + _, err := definitions.CreatePackage(p) + Expect(err).ToNot(HaveOccurred()) + } + visited := make(map[string]interface{}) + + lst := a.ExpandedRevdeps(definitions, visited) Expect(lst).To(ContainElement(b)) Expect(lst).To(ContainElement(c)) Expect(lst).To(ContainElement(d))