mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-06-11 06:24:04 +00:00
List filtering with dependency resolution.
This commit is contained in:
Vendored
+58
-9
@@ -331,21 +331,36 @@ func (l *PackageList) Search(dep Dependency) *Package {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter filters package index by specified queries (ORed together), possibly pulling dependencies
|
// Filter filters package index by specified queries (ORed together), possibly pulling dependencies
|
||||||
func (l *PackageList) Filter(queries []string, withDependencies bool, dependencyOptions int, architecturesList []string) (*PackageList, error) {
|
func (l *PackageList) Filter(queries []string, withDependencies bool, source *PackageList, dependencyOptions int, architecturesList []string) (*PackageList, error) {
|
||||||
|
if !l.indexed {
|
||||||
|
panic("list not indexed, can't filter")
|
||||||
|
}
|
||||||
|
|
||||||
result := NewPackageList()
|
result := NewPackageList()
|
||||||
|
|
||||||
for _, query := range queries {
|
for _, query := range queries {
|
||||||
isDepQuery := strings.IndexAny(query, " (){}=<>") != -1
|
isDepQuery := strings.IndexAny(query, " (){}=<>") != -1
|
||||||
|
|
||||||
if !isDepQuery {
|
if !isDepQuery {
|
||||||
// try to interpret query as package key
|
// try to interpret query as package string representation
|
||||||
p := l.packages[query]
|
|
||||||
if p != nil {
|
// convert Package.String() to Package.Key()
|
||||||
result.Add(p)
|
i := strings.Index(query, "_")
|
||||||
continue
|
if i != -1 {
|
||||||
|
pkg, query := query[:i], query[i+1:]
|
||||||
|
j := strings.LastIndex(query, "_")
|
||||||
|
if j != -1 {
|
||||||
|
version, arch := query[:j], query[j+1:]
|
||||||
|
p := l.packages["P"+arch+" "+pkg+" "+version]
|
||||||
|
if p != nil {
|
||||||
|
result.Add(p)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try as dependency
|
||||||
dep, err := ParseDependency(query)
|
dep, err := ParseDependency(query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if isDepQuery {
|
if isDepQuery {
|
||||||
@@ -355,12 +370,46 @@ func (l *PackageList) Filter(queries []string, withDependencies bool, dependency
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = dep
|
i := sort.Search(len(l.packagesIndex), func(j int) bool { return l.packagesIndex[j].Name >= dep.Pkg })
|
||||||
// -> Search
|
|
||||||
|
|
||||||
|
for i < len(l.packagesIndex) && l.packagesIndex[i].Name == dep.Pkg {
|
||||||
|
p := l.packagesIndex[i]
|
||||||
|
if p.MatchesDependency(dep) {
|
||||||
|
result.Add(p)
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -> Verify dependencies
|
if withDependencies {
|
||||||
|
added := result.Len()
|
||||||
|
|
||||||
|
dependencySource := NewPackageList()
|
||||||
|
dependencySource.Append(source)
|
||||||
|
dependencySource.Append(result)
|
||||||
|
dependencySource.PrepareIndex()
|
||||||
|
|
||||||
|
// while some new dependencies were discovered
|
||||||
|
for added > 0 {
|
||||||
|
added = 0
|
||||||
|
|
||||||
|
// find missing dependencies
|
||||||
|
missing, err := result.VerifyDependencies(dependencyOptions, architecturesList, dependencySource)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to satisfy dependencies
|
||||||
|
for _, dep := range missing {
|
||||||
|
p := l.Search(dep)
|
||||||
|
if p != nil {
|
||||||
|
result.Add(p)
|
||||||
|
dependencySource.Add(p)
|
||||||
|
added++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+39
@@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/smira/aptly/database"
|
"github.com/smira/aptly/database"
|
||||||
. "launchpad.net/gocheck"
|
. "launchpad.net/gocheck"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PackageListSuite struct {
|
type PackageListSuite struct {
|
||||||
@@ -220,6 +221,44 @@ func (s *PackageListSuite) TestSearch(c *C) {
|
|||||||
c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.2"}), IsNil)
|
c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.2"}), IsNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PackageListSuite) TestFilter(c *C) {
|
||||||
|
c.Check(func() { s.list.Filter([]string{"abcd_0.3_i386"}, false, nil, 0, nil) }, Panics, "list not indexed, can't filter")
|
||||||
|
|
||||||
|
_, err := s.il.Filter([]string{"app >3)"}, false, nil, 0, nil)
|
||||||
|
c.Check(err, ErrorMatches, "unable to parse dependency.*")
|
||||||
|
|
||||||
|
plString := func(l *PackageList) string {
|
||||||
|
list := make([]string, 0, l.Len())
|
||||||
|
for _, p := range l.packages {
|
||||||
|
list = append(list, p.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(list)
|
||||||
|
|
||||||
|
return strings.Join(list, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := s.il.Filter([]string{"app_1.1~bp1_i386"}, false, nil, 0, nil)
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(plString(result), Equals, "app_1.1~bp1_i386")
|
||||||
|
|
||||||
|
result, err = s.il.Filter([]string{"app_1.1~bp1_i386", "dpkg_1.7_source", "dpkg_1.8_amd64"}, false, nil, 0, nil)
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(plString(result), Equals, "app_1.1~bp1_i386 dpkg_1.7_source")
|
||||||
|
|
||||||
|
result, err = s.il.Filter([]string{"app", "dpkg (>>1.6.1-3)", "app (>=1.0)", "xyz", "aa (>>3.0)"}, false, nil, 0, nil)
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(plString(result), Equals, "app_1.0_s390 app_1.1~bp1_amd64 app_1.1~bp1_arm app_1.1~bp1_i386 dpkg_1.7_i386 dpkg_1.7_source")
|
||||||
|
|
||||||
|
result, err = s.il.Filter([]string{"app {i386}"}, true, NewPackageList(), 0, []string{"i386"})
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(plString(result), Equals, "app_1.1~bp1_i386 data_1.1~bp1_all dpkg_1.7_i386 lib_1.0_i386 mailer_3.5.8_i386")
|
||||||
|
|
||||||
|
result, err = s.il.Filter([]string{"app (>=0.9)", "lib", "data"}, true, NewPackageList(), 0, []string{"i386", "amd64"})
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(plString(result), Equals, "app_1.0_s390 app_1.1~bp1_amd64 app_1.1~bp1_arm app_1.1~bp1_i386 data_1.1~bp1_all dpkg_1.6.1-3_amd64 dpkg_1.7_i386 lib_1.0_i386 mailer_3.5.8_i386")
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PackageListSuite) TestVerifyDependencies(c *C) {
|
func (s *PackageListSuite) TestVerifyDependencies(c *C) {
|
||||||
missing, err := s.il.VerifyDependencies(0, []string{"i386"}, s.il)
|
missing, err := s.il.VerifyDependencies(0, []string{"i386"}, s.il)
|
||||||
c.Check(err, IsNil)
|
c.Check(err, IsNil)
|
||||||
|
|||||||
Reference in New Issue
Block a user