diff --git a/pkg/package/package.go b/pkg/package/package.go index adb07f1c..7163ac2e 100644 --- a/pkg/package/package.go +++ b/pkg/package/package.go @@ -47,6 +47,7 @@ type Package interface { Requires([]*DefaultPackage) Package Conflicts([]*DefaultPackage) Package Revdeps(PackageDatabase) Packages + ExpandedRevdeps(definitiondb PackageDatabase) Packages LabelDeps(PackageDatabase, string) Packages GetProvides() []*DefaultPackage @@ -416,6 +417,25 @@ func (p *DefaultPackage) Revdeps(definitiondb PackageDatabase) Packages { return versionsInWorld } +// ExpandedRevdeps returns the package reverse dependencies, +// matching also selectors in versions (>, <, >=, <=) +func (p *DefaultPackage) ExpandedRevdeps(definitiondb PackageDatabase) Packages { + var versionsInWorld Packages + 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)...) + } + //} + } + + return versionsInWorld.Unique() +} + func (p *DefaultPackage) LabelDeps(definitiondb PackageDatabase, labelKey string) Packages { var pkgsWithLabelInWorld Packages // TODO: check if integrate some index to improve @@ -481,6 +501,18 @@ func (set Packages) Best(v version.Versioner) Package { return versionsMap[sorted[len(sorted)-1]] } +func (set Packages) Unique() Packages { + var result Packages + uniq := make(map[string]Package) + for _, p := range set { + uniq[p.GetFingerPrint()] = p + } + for _, p := range uniq { + result = append(result, p) + } + return result +} + func (pack *DefaultPackage) BuildFormula(definitiondb PackageDatabase, db PackageDatabase) ([]bf.Formula, error) { p, err := definitiondb.FindPackage(pack) if err != nil { diff --git a/pkg/package/package_test.go b/pkg/package/package_test.go index 31a42032..1238b3b2 100644 --- a/pkg/package/package_test.go +++ b/pkg/package/package_test.go @@ -159,6 +159,66 @@ var _ = Describe("Package", func() { }) }) + Context("revdeps", 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{}) + d := NewPackage("D", "0.1", []*DefaultPackage{c}, []*DefaultPackage{}) + e := NewPackage("E", "0.1", []*DefaultPackage{c}, []*DefaultPackage{}) + + It("doesn't resolve selectors", func() { + definitions := NewInMemoryDatabase(false) + for _, p := range []Package{a, b, c, d, e} { + _, err := definitions.CreatePackage(p) + Expect(err).ToNot(HaveOccurred()) + } + lst := a.Revdeps(definitions) + Expect(len(lst)).To(Equal(0)) + }) + }) + 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{}) + d := NewPackage("D", "0.1", []*DefaultPackage{c}, []*DefaultPackage{}) + e := NewPackage("E", "0.1", []*DefaultPackage{c}, []*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()) + } + lst := a.ExpandedRevdeps(definitions) + 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{}) + 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()) + } + lst := a.ExpandedRevdeps(definitions) + 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("RequiresContains", func() { a := NewPackage("A", ">=1.0", []*DefaultPackage{}, []*DefaultPackage{}) a1 := NewPackage("A", "1.0", []*DefaultPackage{a}, []*DefaultPackage{})