mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-05-05 22:08:27 +00:00
Merge smira/master into pull_multiple_packages
Resolved conflicts arisen following smira's new commits into master.
This commit is contained in:
@@ -18,6 +18,7 @@ func aptlySnapshotPull(cmd *commander.Command, args []string) error {
|
|||||||
|
|
||||||
noDeps := context.flags.Lookup("no-deps").Value.Get().(bool)
|
noDeps := context.flags.Lookup("no-deps").Value.Get().(bool)
|
||||||
noRemove := context.flags.Lookup("no-remove").Value.Get().(bool)
|
noRemove := context.flags.Lookup("no-remove").Value.Get().(bool)
|
||||||
|
allMatches := context.flags.Lookup("all-matches").Value.Get().(bool)
|
||||||
|
|
||||||
// Load <name> snapshot
|
// Load <name> snapshot
|
||||||
snapshot, err := context.CollectionFactory().SnapshotCollection().ByName(args[0])
|
snapshot, err := context.CollectionFactory().SnapshotCollection().ByName(args[0])
|
||||||
@@ -97,24 +98,30 @@ func aptlySnapshotPull(cmd *commander.Command, args []string) error {
|
|||||||
dep := dependencies[i]
|
dep := dependencies[i]
|
||||||
|
|
||||||
// Search for package that can satisfy dependencies
|
// Search for package that can satisfy dependencies
|
||||||
pkg := sourcePackageList.Search(dep)
|
searchResults := sourcePackageList.Search(dep, allMatches)
|
||||||
if pkg == nil {
|
if searchResults == nil {
|
||||||
context.Progress().ColoredPrintf("@y[!]@| @!Dependency %s can't be satisfied with source %s@|", &dep, source)
|
context.Progress().ColoredPrintf("@y[!]@| @!Dependency %s can't be satisfied with source %s@|", &dep, source)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !noRemove {
|
if !noRemove {
|
||||||
// Remove all packages with the same name and architecture
|
// Remove all packages with the same name and architecture
|
||||||
for p := packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}); p != nil; {
|
for _, pkg := range searchResults {
|
||||||
packageList.Remove(p)
|
for pS := packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}, allMatches); pS != nil; {
|
||||||
context.Progress().ColoredPrintf("@r[-]@| %s removed", p)
|
for _, p := range pS {
|
||||||
p = packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name})
|
packageList.Remove(p)
|
||||||
|
context.Progress().ColoredPrintf("@r[-]@| %s removed", p)
|
||||||
|
}
|
||||||
|
pS = packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}, allMatches)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new discovered package
|
// Add new discovered package
|
||||||
packageList.Add(pkg)
|
for _, pkg := range searchResults {
|
||||||
context.Progress().ColoredPrintf("@g[+]@| %s added", pkg)
|
packageList.Add(pkg)
|
||||||
|
context.Progress().ColoredPrintf("@g[+]@| %s added", pkg)
|
||||||
|
}
|
||||||
|
|
||||||
if noDeps {
|
if noDeps {
|
||||||
continue
|
continue
|
||||||
@@ -122,26 +129,28 @@ func aptlySnapshotPull(cmd *commander.Command, args []string) error {
|
|||||||
|
|
||||||
// Find missing dependencies for single added package
|
// Find missing dependencies for single added package
|
||||||
pL := deb.NewPackageList()
|
pL := deb.NewPackageList()
|
||||||
pL.Add(pkg)
|
for _, pkg := range searchResults {
|
||||||
|
pL.Add(pkg)
|
||||||
|
|
||||||
var missing []deb.Dependency
|
var missing []deb.Dependency
|
||||||
missing, err = pL.VerifyDependencies(context.DependencyOptions(), []string{arch}, packageList, nil)
|
missing, err = pL.VerifyDependencies(context.DependencyOptions(), []string{arch}, packageList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
context.Progress().ColoredPrintf("@y[!]@| @!Error while verifying dependencies for pkg %s: %s@|", pkg, err)
|
context.Progress().ColoredPrintf("@y[!]@| @!Error while verifying dependencies for pkg %s: %s@|", pkg, err)
|
||||||
}
|
|
||||||
|
|
||||||
// Append missing dependencies to the list of dependencies to satisfy
|
|
||||||
for _, misDep := range missing {
|
|
||||||
found := false
|
|
||||||
for _, d := range dependencies {
|
|
||||||
if d == misDep {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
// Append missing dependencies to the list of dependencies to satisfy
|
||||||
dependencies = append(dependencies, misDep)
|
for _, misDep := range missing {
|
||||||
|
found := false
|
||||||
|
for _, d := range dependencies {
|
||||||
|
if d == misDep {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
dependencies = append(dependencies, misDep)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,6 +195,8 @@ Example:
|
|||||||
cmd.Flag.Bool("dry-run", false, "don't create destination snapshot, just show what would be pulled")
|
cmd.Flag.Bool("dry-run", false, "don't create destination snapshot, just show what would be pulled")
|
||||||
cmd.Flag.Bool("no-deps", false, "don't process dependencies, just pull listed packages")
|
cmd.Flag.Bool("no-deps", false, "don't process dependencies, just pull listed packages")
|
||||||
cmd.Flag.Bool("no-remove", false, "don't remove other package versions when pulling package")
|
cmd.Flag.Bool("no-remove", false, "don't remove other package versions when pulling package")
|
||||||
|
cmd.Flag.Bool("all-matches", false, "pull all the packages that satisfy the dependency version requirements")
|
||||||
|
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
42
deb/list.go
42
deb/list.go
@@ -263,7 +263,7 @@ func (l *PackageList) VerifyDependencies(options int, architectures []string, so
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if sources.Search(dep) == nil {
|
if sources.Search(dep, false) == nil {
|
||||||
variantsMissing = append(variantsMissing, dep)
|
variantsMissing = append(variantsMissing, dep)
|
||||||
missingCount++
|
missingCount++
|
||||||
} else {
|
} else {
|
||||||
@@ -334,29 +334,47 @@ func (l *PackageList) PrepareIndex() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Search searches package index for specified package
|
// Search searches package index for specified package
|
||||||
func (l *PackageList) Search(dep Dependency) *Package {
|
func (l *PackageList) Search(dep Dependency, allMatches bool) []*Package {
|
||||||
if !l.indexed {
|
if !l.indexed {
|
||||||
panic("list not indexed, can't search")
|
panic("list not indexed, can't search")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
searchResults := []*Package{}
|
||||||
|
|
||||||
if dep.Relation == VersionDontCare {
|
if dep.Relation == VersionDontCare {
|
||||||
for _, p := range l.providesIndex[dep.Pkg] {
|
for _, p := range l.providesIndex[dep.Pkg] {
|
||||||
if p.MatchesArchitecture(dep.Architecture) {
|
if p.MatchesArchitecture(dep.Architecture) {
|
||||||
return p
|
searchResults = append(searchResults, p)
|
||||||
|
|
||||||
|
if !allMatches {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(searchResults) != 0 {
|
||||||
|
return searchResults
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i := sort.Search(len(l.packagesIndex), func(j int) bool { return l.packagesIndex[j].Name >= dep.Pkg })
|
i := sort.Search(len(l.packagesIndex), func(j int) bool { return l.packagesIndex[j].Name >= dep.Pkg })
|
||||||
|
|
||||||
for i < len(l.packagesIndex) && l.packagesIndex[i].Name == dep.Pkg {
|
for i < len(l.packagesIndex) && l.packagesIndex[i].Name == dep.Pkg {
|
||||||
p := l.packagesIndex[i]
|
p := l.packagesIndex[i]
|
||||||
if p.MatchesDependency(dep) {
|
if p.MatchesDependency(dep, allMatches) {
|
||||||
return p
|
searchResults = append(searchResults, p)
|
||||||
|
|
||||||
|
if !allMatches {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(searchResults) != 0 {
|
||||||
|
return searchResults
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,7 +422,7 @@ func (l *PackageList) Filter(queries []string, withDependencies bool, source *Pa
|
|||||||
|
|
||||||
for i < len(l.packagesIndex) && l.packagesIndex[i].Name == dep.Pkg {
|
for i < len(l.packagesIndex) && l.packagesIndex[i].Name == dep.Pkg {
|
||||||
p := l.packagesIndex[i]
|
p := l.packagesIndex[i]
|
||||||
if p.MatchesDependency(dep) {
|
if p.MatchesDependency(dep, false) {
|
||||||
result.Add(p)
|
result.Add(p)
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
@@ -431,11 +449,13 @@ func (l *PackageList) Filter(queries []string, withDependencies bool, source *Pa
|
|||||||
|
|
||||||
// try to satisfy dependencies
|
// try to satisfy dependencies
|
||||||
for _, dep := range missing {
|
for _, dep := range missing {
|
||||||
p := l.Search(dep)
|
searchResults := l.Search(dep, false)
|
||||||
if p != nil {
|
if searchResults != nil {
|
||||||
result.Add(p)
|
for _, p := range searchResults {
|
||||||
dependencySource.Add(p)
|
result.Add(p)
|
||||||
added++
|
dependencySource.Add(p)
|
||||||
|
added++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
112
deb/list_test.go
112
deb/list_test.go
@@ -7,6 +7,43 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type containsChecker struct {
|
||||||
|
*CheckerInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *containsChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||||
|
var (
|
||||||
|
pkgSlice1 []*Package
|
||||||
|
pkgSlice2 []*Package
|
||||||
|
ok bool
|
||||||
|
)
|
||||||
|
|
||||||
|
pkgMap := make (map[*Package]bool)
|
||||||
|
|
||||||
|
|
||||||
|
pkgSlice1, ok = params[0].([]*Package)
|
||||||
|
if !ok {
|
||||||
|
return false, "The first parameter is not a Package slice"
|
||||||
|
}
|
||||||
|
pkgSlice2, ok = params[1].([]*Package)
|
||||||
|
if !ok {
|
||||||
|
return false, "The second parameter is not a Package slice"
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pkg := range pkgSlice2 {
|
||||||
|
pkgMap[pkg] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pkg := range pkgSlice1 {
|
||||||
|
if _, ok := pkgMap[pkg]; !ok {
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var Contains Checker = &containsChecker{&CheckerInfo{Name: "Contains", Params: []string{"Container", "Expected to contain"}}}
|
||||||
|
|
||||||
type PackageListSuite struct {
|
type PackageListSuite struct {
|
||||||
// Simple list with "real" packages from stanzas
|
// Simple list with "real" packages from stanzas
|
||||||
list *PackageList
|
list *PackageList
|
||||||
@@ -14,8 +51,10 @@ type PackageListSuite struct {
|
|||||||
|
|
||||||
// Mocked packages in list
|
// Mocked packages in list
|
||||||
packages []*Package
|
packages []*Package
|
||||||
|
packages2 []*Package
|
||||||
sourcePackages []*Package
|
sourcePackages []*Package
|
||||||
il *PackageList
|
il *PackageList
|
||||||
|
il2 *PackageList
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = Suite(&PackageListSuite{})
|
var _ = Suite(&PackageListSuite{})
|
||||||
@@ -60,6 +99,20 @@ func (s *PackageListSuite) SetUpTest(c *C) {
|
|||||||
}
|
}
|
||||||
s.il.PrepareIndex()
|
s.il.PrepareIndex()
|
||||||
|
|
||||||
|
s.il2 = NewPackageList()
|
||||||
|
s.packages2 = []*Package{
|
||||||
|
&Package{Name: "mailer", Version: "3.5.8", Architecture: "amd64", Source: "postfix (1.3)", Provides: []string{"mail-agent"}, deps: &PackageDependencies{}},
|
||||||
|
&Package{Name: "sendmail", Version: "1.0", Architecture: "amd64", Source: "postfix (1.3)", Provides: []string{"mail-agent"}, deps: &PackageDependencies{}},
|
||||||
|
&Package{Name: "app", Version: "1.1-bp1", Architecture: "amd64", deps: &PackageDependencies{PreDepends: []string{"dpkg (>= 1.6)"}, Depends: []string{"lib (>> 0.9)", "data (>= 1.0)"}}},
|
||||||
|
&Package{Name: "app", Version: "1.1-bp2", Architecture: "amd64", deps: &PackageDependencies{PreDepends: []string{"dpkg (>= 1.6)"}, Depends: []string{"lib (>> 0.9)", "data (>= 1.0)"}}},
|
||||||
|
&Package{Name: "app", Version: "1.2", Architecture: "amd64", deps: &PackageDependencies{PreDepends: []string{"dpkg (>= 1.6)"}, Depends: []string{"lib (>> 0.9) | libx (>= 1.5)", "data (>= 1.0) | mail-agent"}}},
|
||||||
|
&Package{Name: "app", Version: "3.0", Architecture: "amd64", deps: &PackageDependencies{PreDepends: []string{"dpkg >= 1.6)"}, Depends: []string{"lib (>> 0.9)", "data (>= 1.0)"}}},
|
||||||
|
}
|
||||||
|
for _, p := range s.packages2 {
|
||||||
|
s.il2.Add(p)
|
||||||
|
}
|
||||||
|
s.il2.PrepareIndex()
|
||||||
|
|
||||||
s.sourcePackages = []*Package{
|
s.sourcePackages = []*Package{
|
||||||
&Package{Name: "postfix", Version: "1.3", Architecture: "source", SourceArchitecture: "any", IsSource: true, deps: &PackageDependencies{}},
|
&Package{Name: "postfix", Version: "1.3", Architecture: "source", SourceArchitecture: "any", IsSource: true, deps: &PackageDependencies{}},
|
||||||
&Package{Name: "app", Version: "1.1~bp1", Architecture: "source", SourceArchitecture: "any", IsSource: true, deps: &PackageDependencies{}},
|
&Package{Name: "app", Version: "1.1~bp1", Architecture: "source", SourceArchitecture: "any", IsSource: true, deps: &PackageDependencies{}},
|
||||||
@@ -196,31 +249,56 @@ func (s *PackageListSuite) TestAppend(c *C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *PackageListSuite) TestSearch(c *C) {
|
func (s *PackageListSuite) TestSearch(c *C) {
|
||||||
c.Check(func() { s.list.Search(Dependency{Architecture: "i386", Pkg: "app"}) }, Panics, "list not indexed, can't search")
|
//allMatches = False
|
||||||
|
c.Check(func() { s.list.Search(Dependency{Architecture: "i386", Pkg: "app"}, false) }, Panics, "list not indexed, can't search")
|
||||||
|
|
||||||
c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app"}), Equals, s.packages[3])
|
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"}), Equals, s.packages[4])
|
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"}), IsNil)
|
c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "puppy"}, false), IsNil)
|
||||||
|
|
||||||
c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionEqual, Version: "1.1~bp1"}), Equals, s.packages[3])
|
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"}), IsNil)
|
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: VersionLess, Version: "1.1"}), Equals, s.packages[3])
|
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~~"}), IsNil)
|
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: VersionLessOrEqual, Version: "1.1"}), Equals, s.packages[3])
|
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"}), Equals, 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~~"}), IsNil)
|
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: VersionGreater, Version: "1.0"}), Equals, s.packages[3])
|
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"}), IsNil)
|
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: VersionGreaterOrEqual, Version: "1.0"}), Equals, s.packages[3])
|
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"}), Equals, 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"}), IsNil)
|
c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.2"}, false), IsNil)
|
||||||
|
|
||||||
// search w/o version should return package with latest version
|
// search w/o version should return package with latest version
|
||||||
c.Check(s.il.Search(Dependency{Architecture: "source", Pkg: "dpkg"}), Equals, s.packages[13])
|
c.Check(s.il.Search(Dependency{Architecture: "source", Pkg: "dpkg"}, false), 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", 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), 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: 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: 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: 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: 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PackageListSuite) TestFilter(c *C) {
|
func (s *PackageListSuite) TestFilter(c *C) {
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ func (p *Package) MatchesArchitecture(arch string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MatchesDependency checks whether package matches specified dependency
|
// MatchesDependency checks whether package matches specified dependency
|
||||||
func (p *Package) MatchesDependency(dep Dependency) bool {
|
func (p *Package) MatchesDependency(dep Dependency, allMatches bool) bool {
|
||||||
if dep.Pkg != p.Name {
|
if dep.Pkg != p.Name {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -212,9 +212,15 @@ func (p *Package) MatchesDependency(dep Dependency) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
r := CompareVersions(p.Version, dep.Version)
|
r := CompareVersions(p.Version, dep.Version)
|
||||||
|
|
||||||
switch dep.Relation {
|
switch dep.Relation {
|
||||||
case VersionEqual:
|
case VersionEqual:
|
||||||
return r == 0
|
if allMatches {
|
||||||
|
rn := CompareVersions(p.Version, dep.NextVersion())
|
||||||
|
return r+rn == 0 || r == 0
|
||||||
|
} else {
|
||||||
|
return r == 0
|
||||||
|
}
|
||||||
case VersionLess:
|
case VersionLess:
|
||||||
return r < 0
|
return r < 0
|
||||||
case VersionGreater:
|
case VersionGreater:
|
||||||
|
|||||||
@@ -172,38 +172,44 @@ func (s *PackageSuite) TestMatchesDependency(c *C) {
|
|||||||
p := NewPackageFromControlFile(s.stanza)
|
p := NewPackageFromControlFile(s.stanza)
|
||||||
|
|
||||||
// exact match
|
// exact match
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionEqual, Version: "7.40-2"}), Equals, true)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionEqual, Version: "7.40-2"}, false), Equals, true)
|
||||||
|
|
||||||
|
// exact match, same version, no revision specified
|
||||||
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionEqual, Version: "7.40"}, false), Equals, false)
|
||||||
|
|
||||||
|
// non-exact match, same version, no revision specified
|
||||||
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionEqual, Version: "7.40"}, true), Equals, true)
|
||||||
|
|
||||||
// different name
|
// different name
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena", Architecture: "i386", Relation: VersionEqual, Version: "7.40-2"}), Equals, false)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena", Architecture: "i386", Relation: VersionEqual, Version: "7.40-2"}, false), Equals, false)
|
||||||
|
|
||||||
// different version
|
// different version
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionEqual, Version: "7.40-3"}), Equals, false)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionEqual, Version: "7.40-3"}, false), Equals, false)
|
||||||
|
|
||||||
// different arch
|
// different arch
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "amd64", Relation: VersionEqual, Version: "7.40-2"}), Equals, false)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "amd64", Relation: VersionEqual, Version: "7.40-2"}, false), Equals, false)
|
||||||
|
|
||||||
// empty arch
|
// empty arch
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "", Relation: VersionEqual, Version: "7.40-2"}), Equals, true)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "", Relation: VersionEqual, Version: "7.40-2"}, false), Equals, true)
|
||||||
|
|
||||||
// version don't care
|
// version don't care
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionDontCare, Version: ""}), Equals, true)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionDontCare, Version: ""}, false), Equals, true)
|
||||||
|
|
||||||
// >
|
// >
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionGreater, Version: "7.40-2"}), Equals, false)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionGreater, Version: "7.40-2"}, false), Equals, false)
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionGreater, Version: "7.40-1"}), Equals, true)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionGreater, Version: "7.40-1"}, false), Equals, true)
|
||||||
|
|
||||||
// <
|
// <
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionLess, Version: "7.40-2"}), Equals, false)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionLess, Version: "7.40-2"}, false), Equals, false)
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionLess, Version: "7.40-3"}), Equals, true)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionLess, Version: "7.40-3"}, false), Equals, true)
|
||||||
|
|
||||||
// >=
|
// >=
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionGreaterOrEqual, Version: "7.40-2"}), Equals, true)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionGreaterOrEqual, Version: "7.40-2"}, false), Equals, true)
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionGreaterOrEqual, Version: "7.40-3"}), Equals, false)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionGreaterOrEqual, Version: "7.40-3"}, false), Equals, false)
|
||||||
|
|
||||||
// <=
|
// <=
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionLessOrEqual, Version: "7.40-2"}), Equals, true)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionLessOrEqual, Version: "7.40-2"}, false), Equals, true)
|
||||||
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionLessOrEqual, Version: "7.40-1"}), Equals, false)
|
c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionLessOrEqual, Version: "7.40-1"}, false), Equals, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PackageSuite) TestGetDependencies(c *C) {
|
func (s *PackageSuite) TestGetDependencies(c *C) {
|
||||||
|
|||||||
@@ -188,6 +188,29 @@ type Dependency struct {
|
|||||||
Architecture string
|
Architecture string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextVersion returns the next version of a dependency (eg. if d.Version = 1.9, it returns 1.10)
|
||||||
|
func (d *Dependency) NextVersion() string {
|
||||||
|
l := len(d.Version)
|
||||||
|
|
||||||
|
if l == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
i := l
|
||||||
|
for i > 0 {
|
||||||
|
_, err := strconv.ParseUint(d.Version[i-1:l],10,0)
|
||||||
|
if err != nil { break }
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := strconv.ParseUint(d.Version[i:l],10,0)
|
||||||
|
if err != nil {
|
||||||
|
return d.Version
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.Version[0:i] + strconv.Itoa(int(v)+1)
|
||||||
|
}
|
||||||
|
|
||||||
// Hash calculates some predefined unique ID of Dependency
|
// Hash calculates some predefined unique ID of Dependency
|
||||||
func (d *Dependency) Hash() string {
|
func (d *Dependency) Hash() string {
|
||||||
return fmt.Sprintf("%s:%s:%d:%s", d.Architecture, d.Pkg, d.Relation, d.Version)
|
return fmt.Sprintf("%s:%s:%d:%s", d.Architecture, d.Pkg, d.Relation, d.Version)
|
||||||
|
|||||||
@@ -217,3 +217,45 @@ func (s *VersionSuite) TestDependencyString(c *C) {
|
|||||||
d.Architecture = "i386"
|
d.Architecture = "i386"
|
||||||
c.Check(d.String(), Equals, "dpkg [i386]")
|
c.Check(d.String(), Equals, "dpkg [i386]")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *VersionSuite) TestDependencyNextVersion(c *C){
|
||||||
|
d, _ := ParseDependency("dpkg(=1.7)")
|
||||||
|
d.Architecture = "i386"
|
||||||
|
c.Check(d.NextVersion(), Equals, "1.8")
|
||||||
|
|
||||||
|
d, _ = ParseDependency("dpkg(=1.9)")
|
||||||
|
d.Architecture = "i386"
|
||||||
|
c.Check(d.NextVersion(), Equals, "1.10")
|
||||||
|
|
||||||
|
d, _ = ParseDependency("dpkg(=9)")
|
||||||
|
d.Architecture = "i386"
|
||||||
|
c.Check(d.NextVersion(), Equals, "10")
|
||||||
|
|
||||||
|
d, _ = ParseDependency("dpkg(=9.909)")
|
||||||
|
d.Architecture = "i386"
|
||||||
|
c.Check(d.NextVersion(), Equals, "9.910")
|
||||||
|
|
||||||
|
d, _ = ParseDependency("dpkg(=9.0.9)")
|
||||||
|
d.Architecture = "i386"
|
||||||
|
c.Check(d.NextVersion(), Equals, "9.0.10")
|
||||||
|
|
||||||
|
d, _ = ParseDependency("dpkg(=9.0.100)")
|
||||||
|
d.Architecture = "i386"
|
||||||
|
c.Check(d.NextVersion(), Equals, "9.0.101")
|
||||||
|
|
||||||
|
d, _ = ParseDependency("dpkg(=9.0.0-209)")
|
||||||
|
d.Architecture = "i386"
|
||||||
|
c.Check(d.NextVersion(), Equals, "9.0.0-210")
|
||||||
|
|
||||||
|
d, _ = ParseDependency("dpkg(=9.0.0-209rel)")
|
||||||
|
d.Architecture = "i386"
|
||||||
|
c.Check(d.NextVersion(), Equals, "9.0.0-209rel")
|
||||||
|
|
||||||
|
d, _ = ParseDependency("dpkg(=9.0.0-rel219)")
|
||||||
|
d.Architecture = "i386"
|
||||||
|
c.Check(d.NextVersion(), Equals, "9.0.0-rel220")
|
||||||
|
|
||||||
|
d, _ = ParseDependency("dpkg")
|
||||||
|
d.Architecture = "i386"
|
||||||
|
c.Check(d.NextVersion(), Equals, "")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user