diff --git a/api/snapshot.go b/api/snapshot.go index 18aa6440..1a9c2278 100644 --- a/api/snapshot.go +++ b/api/snapshot.go @@ -653,7 +653,7 @@ func apiSnapshotsPull(c *gin.Context) { // If we haven't seen such name-architecture pair and were instructed to remove, remove it if !noRemove && !seen { // Remove all packages with the same name and architecture - packageSearchResults := toPackageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}, true) + packageSearchResults := toPackageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}, true, false) for _, p := range packageSearchResults { toPackageList.Remove(p) removedPackages = append(removedPackages, p.String()) diff --git a/cmd/snapshot_pull.go b/cmd/snapshot_pull.go index 884b50ff..9c2559f5 100644 --- a/cmd/snapshot_pull.go +++ b/cmd/snapshot_pull.go @@ -112,7 +112,7 @@ func aptlySnapshotPull(cmd *commander.Command, args []string) error { // If we haven't seen such name-architecture pair and were instructed to remove, remove it if !noRemove && !seen { // Remove all packages with the same name and architecture - pS := packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}, true) + pS := packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}, true, false) for _, p := range pS { packageList.Remove(p) context.Progress().ColoredPrintf("@r[-]@| %s removed", p) diff --git a/deb/import.go b/deb/import.go index e1da5101..99d52be8 100644 --- a/deb/import.go +++ b/deb/import.go @@ -209,7 +209,7 @@ func ImportPackageFiles(list *PackageList, packageFiles []string, forceReplace b } if forceReplace { - conflictingPackages := list.Search(Dependency{Pkg: p.Name, Version: p.Version, Relation: VersionEqual, Architecture: p.Architecture}, true) + conflictingPackages := list.Search(Dependency{Pkg: p.Name, Version: p.Version, Relation: VersionEqual, Architecture: p.Architecture}, true, false) for _, cp := range conflictingPackages { reporter.Removed("%s removed due to conflict with package being added", cp) list.Remove(cp) diff --git a/deb/list.go b/deb/list.go index f9a8244a..e88069f2 100644 --- a/deb/list.go +++ b/deb/list.go @@ -347,7 +347,7 @@ func (l *PackageList) VerifyDependencies(options int, architectures []string, so hash := dep.Hash() satisfied, ok := cache[hash] if !ok { - satisfied = sources.Search(dep, false) != nil + satisfied = sources.Search(dep, false, true) != nil cache[hash] = satisfied } @@ -459,7 +459,7 @@ func (l *PackageList) SearchByKey(arch, name, version string) (result *PackageLi } // Search searches package index for specified package(s) using optimized queries -func (l *PackageList) Search(dep Dependency, allMatches bool) (searchResults []*Package) { +func (l *PackageList) Search(dep Dependency, allMatches bool, searchProvided bool) (searchResults []*Package) { if !l.indexed { panic("list not indexed, can't search") } @@ -479,18 +479,20 @@ func (l *PackageList) Search(dep Dependency, allMatches bool) (searchResults []* i++ } - providers, ok := l.providesIndex[dep.Pkg] - if !ok { - return - } - for _, p := range providers { - if dep.Architecture == "" || p.MatchesArchitecture(dep.Architecture) { - if p.MatchesDependency(dep) { - searchResults = append(searchResults, p) - } + if searchProvided { + providers, ok := l.providesIndex[dep.Pkg] + if !ok { + return + } + for _, p := range providers { + if dep.Architecture == "" || p.MatchesArchitecture(dep.Architecture) { + if p.MatchesDependency(dep) { + searchResults = append(searchResults, p) + } - if !allMatches { - return + if !allMatches { + return + } } } } @@ -544,15 +546,16 @@ func (l *PackageList) FilterWithProgress(queries []PackageQuery, withDependencie // // when follow-all-variants is enabled, we need to try to expand anyway, // as even if dependency is satisfied now, there might be other ways to satisfy dependency - if result.Search(dep, false) != nil { + // FIXME: do not search twice + if result.Search(dep, false, true) != nil { if dependencyOptions&DepVerboseResolve == DepVerboseResolve && progress != nil { - progress.ColoredPrintf("@{y}Already satisfied dependency@|: %s with %s", &dep, result.Search(dep, true)) + progress.ColoredPrintf("@{y}Already satisfied dependency@|: %s with %s", &dep, result.Search(dep, true, true)) } continue } } - searchResults := l.Search(dep, true) + searchResults := l.Search(dep, true, true) if len(searchResults) > 0 { for _, p := range searchResults { if result.Has(p) { diff --git a/deb/list_test.go b/deb/list_test.go index 0cb04b76..4209f125 100644 --- a/deb/list_test.go +++ b/deb/list_test.go @@ -251,63 +251,63 @@ func (s *PackageListSuite) TestAppend(c *C) { func (s *PackageListSuite) TestSearch(c *C) { //allMatches = False - c.Check(func() { s.list.Search(Dependency{Architecture: "i386", Pkg: "app"}, false) }, Panics, "list not indexed, can't search") + c.Check(func() { s.list.Search(Dependency{Architecture: "i386", Pkg: "app"}, false, true) }, Panics, "list not indexed, can't search") - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app"}, false), DeepEquals, []*Package{s.packages[3]}) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "mail-agent"}, false), DeepEquals, []*Package{s.packages[4]}) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "puppy"}, false), IsNil) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app"}, false, true), DeepEquals, []*Package{s.packages[3]}) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "mail-agent"}, false, true), DeepEquals, []*Package{s.packages[4]}) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "puppy"}, false, true), IsNil) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionEqual, Version: "1.1~bp1"}, false), DeepEquals, []*Package{s.packages[3]}) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionEqual, Version: "1.1~bp2"}, false), IsNil) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionEqual, Version: "1.1~bp1"}, false, true), DeepEquals, []*Package{s.packages[3]}) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionEqual, Version: "1.1~bp2"}, false, true), IsNil) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionLess, Version: "1.1"}, false), DeepEquals, []*Package{s.packages[3]}) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionLess, Version: "1.1~~"}, false), IsNil) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionLess, Version: "1.1"}, false, true), DeepEquals, []*Package{s.packages[3]}) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionLess, Version: "1.1~~"}, false, true), IsNil) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.1"}, false), DeepEquals, []*Package{s.packages[3]}) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.1~bp1"}, false), DeepEquals, []*Package{s.packages[3]}) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.1~~"}, false), IsNil) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.1"}, false, true), DeepEquals, []*Package{s.packages[3]}) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.1~bp1"}, false, true), DeepEquals, []*Package{s.packages[3]}) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.1~~"}, false, true), IsNil) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreater, Version: "1.0"}, false), DeepEquals, []*Package{s.packages[3]}) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreater, Version: "1.2"}, false), IsNil) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreater, Version: "1.0"}, false, true), DeepEquals, []*Package{s.packages[3]}) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreater, Version: "1.2"}, false, true), IsNil) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.0"}, false), DeepEquals, []*Package{s.packages[3]}) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.1~bp1"}, false), DeepEquals, []*Package{s.packages[3]}) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.2"}, false), IsNil) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.0"}, false, true), DeepEquals, []*Package{s.packages[3]}) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.1~bp1"}, false, true), DeepEquals, []*Package{s.packages[3]}) + c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.2"}, false, true), IsNil) // search w/o version should return package with latest version - c.Check(s.il.Search(Dependency{Architecture: "source", Pkg: "dpkg"}, false), DeepEquals, []*Package{s.packages[13]}) + c.Check(s.il.Search(Dependency{Architecture: "source", Pkg: "dpkg"}, false, true), DeepEquals, []*Package{s.packages[13]}) // allMatches = True - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app"}, true), Contains, []*Package{s.packages2[2], s.packages2[3], s.packages2[4], s.packages2[5]}) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "mail-agent"}, true), Contains, []*Package{s.packages2[0], s.packages2[1]}) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "puppy"}, true), IsNil) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app"}, true, true), Contains, []*Package{s.packages2[2], s.packages2[3], s.packages2[4], s.packages2[5]}) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "mail-agent"}, true, true), Contains, []*Package{s.packages2[0], s.packages2[1]}) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "puppy"}, true, true), IsNil) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionEqual, Version: "1.1"}, true), Contains, []*Package{s.packages2[2], s.packages2[3]}) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionEqual, Version: "1.1"}, true, true), Contains, []*Package{s.packages2[2], s.packages2[3]}) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionEqual, Version: "1.1"}, true), Contains, []*Package{s.packages2[2], s.packages2[3]}) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionEqual, Version: "3"}, true), Contains, []*Package{s.packages2[5]}) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionEqual, Version: "1.1"}, true, true), Contains, []*Package{s.packages2[2], s.packages2[3]}) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionEqual, Version: "3"}, true, true), Contains, []*Package{s.packages2[5]}) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionLess, Version: "1.2"}, true), Contains, []*Package{s.packages2[2], s.packages2[3]}) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionLess, Version: "1.1~"}, true), IsNil) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionLess, Version: "1.2"}, true, true), Contains, []*Package{s.packages2[2], s.packages2[3]}) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionLess, Version: "1.1~"}, true, true), IsNil) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.2"}, true), Contains, []*Package{s.packages2[2], s.packages2[3], s.packages2[4]}) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.1-bp1"}, true), Contains, []*Package{s.packages2[2]}) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.0"}, true), IsNil) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.2"}, true, true), Contains, []*Package{s.packages2[2], s.packages2[3], s.packages2[4]}) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.1-bp1"}, true, true), Contains, []*Package{s.packages2[2]}) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionLessOrEqual, Version: "1.0"}, true, true), IsNil) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionGreater, Version: "1.1"}, true), Contains, []*Package{s.packages2[2], s.packages2[3], s.packages2[4], s.packages2[5]}) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionGreater, Version: "5.0"}, true), IsNil) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionGreater, Version: "1.1"}, true, true), Contains, []*Package{s.packages2[2], s.packages2[3], s.packages2[4], s.packages2[5]}) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionGreater, Version: "5.0"}, true, true), IsNil) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.2"}, true), Contains, []*Package{s.packages2[4], s.packages2[5]}) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.1~bp1"}, true), Contains, []*Package{s.packages2[2], s.packages2[3], s.packages2[4], s.packages2[5]}) - c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "5.0"}, true), IsNil) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.2"}, true, true), Contains, []*Package{s.packages2[4], s.packages2[5]}) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.1~bp1"}, true, true), Contains, []*Package{s.packages2[2], s.packages2[3], s.packages2[4], s.packages2[5]}) + c.Check(s.il2.Search(Dependency{Architecture: "amd64", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "5.0"}, true, true), IsNil) // Provides with version number python3CFFIBackend := &Package{Name: "python3-cffi-backend", Version: "1.15.1-5+b1", Architecture: "amd64", Provides: []string{"python3-cffi-backend-api-9729", "python3-cffi-backend-api-max (= 10495)", "python3-cffi-backend-api-min (= 9729)"}} err := s.il2.Add(python3CFFIBackend) c.Check(err, IsNil) - c.Check(s.il2.Search(Dependency{Pkg: "python3-cffi-backend-api-max", Relation: VersionGreaterOrEqual, Version: "9729"}, false), DeepEquals, []*Package{python3CFFIBackend}) - c.Check(s.il2.Search(Dependency{Pkg: "python3-cffi-backend-api-max", Relation: VersionLess, Version: "9729"}, false), IsNil) - c.Check(s.il2.Search(Dependency{Pkg: "python3-cffi-backend-api-max", Relation: VersionDontCare}, false), DeepEquals, []*Package{python3CFFIBackend}) + c.Check(s.il2.Search(Dependency{Pkg: "python3-cffi-backend-api-max", Relation: VersionGreaterOrEqual, Version: "9729"}, false, true), DeepEquals, []*Package{python3CFFIBackend}) + c.Check(s.il2.Search(Dependency{Pkg: "python3-cffi-backend-api-max", Relation: VersionLess, Version: "9729"}, false, true), IsNil) + c.Check(s.il2.Search(Dependency{Pkg: "python3-cffi-backend-api-max", Relation: VersionDontCare}, false, true), DeepEquals, []*Package{python3CFFIBackend}) } func (s *PackageListSuite) TestFilter(c *C) { diff --git a/deb/package_collection.go b/deb/package_collection.go index c7e6a300..0027f1de 100644 --- a/deb/package_collection.go +++ b/deb/package_collection.go @@ -317,7 +317,7 @@ func (collection *PackageCollection) Scan(q PackageQuery) (result *PackageList) } // Search is not implemented -func (collection *PackageCollection) Search(_ Dependency, _ bool) (searchResults []*Package) { +func (collection *PackageCollection) Search(_ Dependency, _ bool, _ bool) (searchResults []*Package) { panic("Not implemented") } diff --git a/deb/query.go b/deb/query.go index 1de9e95b..ad0ad17a 100644 --- a/deb/query.go +++ b/deb/query.go @@ -20,7 +20,7 @@ type PackageLike interface { // PackageCatalog is abstraction on top of PackageCollection and PackageList type PackageCatalog interface { Scan(q PackageQuery) (result *PackageList) - Search(dep Dependency, allMatches bool) (searchResults []*Package) + Search(dep Dependency, allMatches bool, searchProvided bool) (searchResults []*Package) SearchSupported() bool SearchByKey(arch, name, version string) (result *PackageList) } @@ -244,7 +244,7 @@ func (q *DependencyQuery) Fast(list PackageCatalog) bool { func (q *DependencyQuery) Query(list PackageCatalog) (result *PackageList) { if q.Fast(list) { result = NewPackageList() - for _, pkg := range list.Search(q.Dep, true) { + for _, pkg := range list.Search(q.Dep, true, true) { result.Add(pkg) } } else {