From 3cf281965b7e5aa774f45a1a210bddc59303ac1e Mon Sep 17 00:00:00 2001 From: Simon Aquino Date: Fri, 27 Jun 2014 01:40:41 +0100 Subject: [PATCH 1/8] Implementation of all-matches functionality + tests When performing an *aptly snapshot pull*, users might list dependency versions that can potentially match multiple packages in the source snapshot. However, the current implementation of the 'snapshot pull' command only allows one package to be pulled from a snapshot at a time for a given dependency. The newly implemented all-matches flag allows users to pull all the matching packages from a source snapshot, provided that they satisfy the version requirements indicated by the dependencies. The all-matches flag defaults to false and only produces the described behaviour when it is explicitly set to true. --- cmd/snapshot_pull.go | 61 ++++++++++++++---------- deb/list.go | 42 +++++++++++----- deb/list_test.go | 111 ++++++++++++++++++++++++++++++++++++------- deb/package.go | 10 +++- deb/package_test.go | 34 +++++++------ deb/version.go | 23 +++++++++ deb/version_test.go | 42 ++++++++++++++++ 7 files changed, 255 insertions(+), 68 deletions(-) diff --git a/cmd/snapshot_pull.go b/cmd/snapshot_pull.go index dcf3338f..956b29c2 100644 --- a/cmd/snapshot_pull.go +++ b/cmd/snapshot_pull.go @@ -18,6 +18,7 @@ func aptlySnapshotPull(cmd *commander.Command, args []string) error { noDeps := context.flags.Lookup("no-deps").Value.Get().(bool) noRemove := context.flags.Lookup("no-remove").Value.Get().(bool) + allMatches := context.flags.Lookup("all-matches").Value.Get().(bool) // Load snapshot snapshot, err := context.CollectionFactory().SnapshotCollection().ByName(args[0]) @@ -97,24 +98,30 @@ func aptlySnapshotPull(cmd *commander.Command, args []string) error { dep := dependencies[i] // Search for package that can satisfy dependencies - pkg := sourcePackageList.Search(dep) - if pkg == nil { + searchResults := sourcePackageList.Search(dep, allMatches) + if searchResults == nil { context.Progress().ColoredPrintf("@y[!]@| @!Dependency %s can't be satisfied with source %s@|", &dep, source) continue } if !noRemove { // Remove all packages with the same name and architecture - for p := packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}); p != nil; { - packageList.Remove(p) - context.Progress().ColoredPrintf("@r[-]@| %s removed", p) - p = packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}) + for _, pkg := range searchResults { + for pS := packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}, allMatches); pS != nil; { + for _, p := range pS { + 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 - packageList.Add(pkg) - context.Progress().ColoredPrintf("@g[+]@| %s added", pkg) + for _, pkg := range searchResults { + packageList.Add(pkg) + context.Progress().ColoredPrintf("@g[+]@| %s added", pkg) + } if noDeps { continue @@ -122,26 +129,28 @@ func aptlySnapshotPull(cmd *commander.Command, args []string) error { // Find missing dependencies for single added package pL := deb.NewPackageList() - pL.Add(pkg) + for _, pkg := range searchResults { + pL.Add(pkg) - var missing []deb.Dependency - missing, err = pL.VerifyDependencies(context.DependencyOptions(), []string{arch}, packageList, nil) - if err != nil { - 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 - } + var missing []deb.Dependency + missing, err = pL.VerifyDependencies(context.DependencyOptions(), []string{arch}, packageList, nil) + if err != nil { + context.Progress().ColoredPrintf("@y[!]@| @!Error while verifying dependencies for pkg %s: %s@|", pkg, err) } - if !found { - dependencies = append(dependencies, misDep) + // 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 { + 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("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("all-matches", false, "pull all the packages that satisfy the dependency version requirements") + return cmd } diff --git a/deb/list.go b/deb/list.go index b615b5d2..e63e859f 100644 --- a/deb/list.go +++ b/deb/list.go @@ -263,7 +263,7 @@ func (l *PackageList) VerifyDependencies(options int, architectures []string, so continue } - if sources.Search(dep) == nil { + if sources.Search(dep, false) == nil { variantsMissing = append(variantsMissing, dep) missingCount++ } else { @@ -326,29 +326,47 @@ func (l *PackageList) PrepareIndex() { } // 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 { panic("list not indexed, can't search") } + searchResults := []*Package{} + if dep.Relation == VersionDontCare { for _, p := range l.providesIndex[dep.Pkg] { 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 }) for i < len(l.packagesIndex) && l.packagesIndex[i].Name == dep.Pkg { p := l.packagesIndex[i] - if p.MatchesDependency(dep) { - return p + if p.MatchesDependency(dep, allMatches) { + searchResults = append(searchResults, p) + + if !allMatches { + break + } } i++ } + + if len(searchResults) != 0 { + return searchResults + } + return nil } @@ -396,7 +414,7 @@ func (l *PackageList) Filter(queries []string, withDependencies bool, source *Pa for i < len(l.packagesIndex) && l.packagesIndex[i].Name == dep.Pkg { p := l.packagesIndex[i] - if p.MatchesDependency(dep) { + if p.MatchesDependency(dep, false) { result.Add(p) } i++ @@ -423,11 +441,13 @@ func (l *PackageList) Filter(queries []string, withDependencies bool, source *Pa // try to satisfy dependencies for _, dep := range missing { - p := l.Search(dep) - if p != nil { - result.Add(p) - dependencySource.Add(p) - added++ + searchResults := l.Search(dep, false) + if searchResults != nil { + for _, p := range searchResults { + result.Add(p) + dependencySource.Add(p) + added++ + } } } } diff --git a/deb/list_test.go b/deb/list_test.go index 953f5e85..4fb8fb0a 100644 --- a/deb/list_test.go +++ b/deb/list_test.go @@ -7,6 +7,43 @@ import ( "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 { // Simple list with "real" packages from stanzas list *PackageList @@ -14,8 +51,10 @@ type PackageListSuite struct { // Mocked packages in list packages []*Package + packages2 []*Package sourcePackages []*Package il *PackageList + il2 *PackageList } var _ = Suite(&PackageListSuite{}) @@ -60,6 +99,20 @@ func (s *PackageListSuite) SetUpTest(c *C) { } 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{ &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{}}, @@ -196,28 +249,54 @@ func (s *PackageListSuite) TestAppend(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: "mail-agent"}), Equals, s.packages[4]) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "puppy"}), IsNil) + 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", 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~bp2"}), 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: VersionLess, Version: "1.1"}), Equals, 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), 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: VersionLessOrEqual, Version: "1.1"}), Equals, 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~~"}), 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: VersionGreater, Version: "1.0"}), Equals, 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.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: 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) + + // 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) - 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.1~bp1"}), Equals, s.packages[3]) - c.Check(s.il.Search(Dependency{Architecture: "i386", Pkg: "app", Relation: VersionGreaterOrEqual, Version: "1.2"}), IsNil) } func (s *PackageListSuite) TestFilter(c *C) { diff --git a/deb/package.go b/deb/package.go index 8569ad43..4933a22e 100644 --- a/deb/package.go +++ b/deb/package.go @@ -198,7 +198,7 @@ func (p *Package) MatchesArchitecture(arch string) bool { } // 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 { return false } @@ -212,9 +212,15 @@ func (p *Package) MatchesDependency(dep Dependency) bool { } r := CompareVersions(p.Version, dep.Version) + switch dep.Relation { 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: return r < 0 case VersionGreater: diff --git a/deb/package_test.go b/deb/package_test.go index 815da84d..3d37bd8e 100644 --- a/deb/package_test.go +++ b/deb/package_test.go @@ -172,38 +172,44 @@ func (s *PackageSuite) TestMatchesDependency(c *C) { p := NewPackageFromControlFile(s.stanza) // 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 - 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 - 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 - 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 - 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 - 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-1"}), Equals, true) + 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"}, 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-3"}), Equals, true) + 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"}, 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-3"}), Equals, false) + 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"}, 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-1"}), Equals, false) + 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"}, false), Equals, false) } func (s *PackageSuite) TestGetDependencies(c *C) { diff --git a/deb/version.go b/deb/version.go index e7b11584..6341bd73 100644 --- a/deb/version.go +++ b/deb/version.go @@ -188,6 +188,29 @@ type Dependency struct { 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 func (d *Dependency) Hash() string { return fmt.Sprintf("%s:%s:%d:%s", d.Architecture, d.Pkg, d.Relation, d.Version) diff --git a/deb/version_test.go b/deb/version_test.go index 53a47b95..923dc5f5 100644 --- a/deb/version_test.go +++ b/deb/version_test.go @@ -217,3 +217,45 @@ func (s *VersionSuite) TestDependencyString(c *C) { d.Architecture = "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, "") +} From 566604d4ba442a27012a841f9d25858bcbdde6fe Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 10 Jul 2014 00:04:48 +0400 Subject: [PATCH 2/8] Revert changes related to NextVersion. #70 It would be done in a bit different way: by introducing powerful search queries. --- deb/version.go | 23 ----------------------- deb/version_test.go | 42 ------------------------------------------ 2 files changed, 65 deletions(-) diff --git a/deb/version.go b/deb/version.go index 6341bd73..e7b11584 100644 --- a/deb/version.go +++ b/deb/version.go @@ -188,29 +188,6 @@ type Dependency struct { 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 func (d *Dependency) Hash() string { return fmt.Sprintf("%s:%s:%d:%s", d.Architecture, d.Pkg, d.Relation, d.Version) diff --git a/deb/version_test.go b/deb/version_test.go index 923dc5f5..53a47b95 100644 --- a/deb/version_test.go +++ b/deb/version_test.go @@ -217,45 +217,3 @@ func (s *VersionSuite) TestDependencyString(c *C) { d.Architecture = "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, "") -} From 1c30b2b9de1e8aec41a2423afce52ef6f5abc6bf Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 10 Jul 2014 00:10:53 +0400 Subject: [PATCH 3/8] Simplification: we are already able to search for all packages. #70 --- cmd/snapshot_pull.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/cmd/snapshot_pull.go b/cmd/snapshot_pull.go index 956b29c2..c4a6c4f3 100644 --- a/cmd/snapshot_pull.go +++ b/cmd/snapshot_pull.go @@ -107,12 +107,10 @@ func aptlySnapshotPull(cmd *commander.Command, args []string) error { if !noRemove { // Remove all packages with the same name and architecture for _, pkg := range searchResults { - for pS := packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}, allMatches); pS != nil; { - for _, p := range pS { - packageList.Remove(p) - context.Progress().ColoredPrintf("@r[-]@| %s removed", p) - } - pS = packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}, allMatches) + pS := packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}, true) + for _, p := range pS { + packageList.Remove(p) + context.Progress().ColoredPrintf("@r[-]@| %s removed", p) } } } @@ -197,6 +195,5 @@ Example: 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 } From 81d506b226316fdb52593adde433697ce121e7ce Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 10 Jul 2014 00:13:19 +0400 Subject: [PATCH 4/8] Dependencies should be matched for each package one by one. #70 --- cmd/snapshot_pull.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/snapshot_pull.go b/cmd/snapshot_pull.go index c4a6c4f3..7604f0ec 100644 --- a/cmd/snapshot_pull.go +++ b/cmd/snapshot_pull.go @@ -125,9 +125,9 @@ func aptlySnapshotPull(cmd *commander.Command, args []string) error { continue } - // Find missing dependencies for single added package - pL := deb.NewPackageList() + // Find missing dependencies, for each added package for _, pkg := range searchResults { + pL := deb.NewPackageList() pL.Add(pkg) var missing []deb.Dependency From bdbb5acb115c2217e9bf30862870e9c0d1bba947 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 10 Jul 2014 00:20:28 +0400 Subject: [PATCH 5/8] Remove 'allMatches' on version equal. #70 --- deb/list.go | 4 ++-- deb/package.go | 13 ++++--------- deb/package_test.go | 45 +++++++++++++++++++++------------------------ 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/deb/list.go b/deb/list.go index cfc3b79c..1dcc2494 100644 --- a/deb/list.go +++ b/deb/list.go @@ -360,7 +360,7 @@ func (l *PackageList) Search(dep Dependency, allMatches bool) []*Package { for i < len(l.packagesIndex) && l.packagesIndex[i].Name == dep.Pkg { p := l.packagesIndex[i] - if p.MatchesDependency(dep, allMatches) { + if p.MatchesDependency(dep) { searchResults = append(searchResults, p) if !allMatches { @@ -422,7 +422,7 @@ func (l *PackageList) Filter(queries []string, withDependencies bool, source *Pa for i < len(l.packagesIndex) && l.packagesIndex[i].Name == dep.Pkg { p := l.packagesIndex[i] - if p.MatchesDependency(dep, false) { + if p.MatchesDependency(dep) { result.Add(p) } i++ diff --git a/deb/package.go b/deb/package.go index 4933a22e..01b638dd 100644 --- a/deb/package.go +++ b/deb/package.go @@ -43,7 +43,7 @@ func NewPackageFromControlFile(input Stanza) *Package { Version: input["Version"], Architecture: input["Architecture"], Source: input["Source"], - V06Plus: true, + V06Plus: true, } delete(input, "Package") @@ -92,7 +92,7 @@ func NewSourcePackageFromControlFile(input Stanza) (*Package, error) { Version: input["Version"], Architecture: "source", SourceArchitecture: input["Architecture"], - V06Plus: true, + V06Plus: true, } delete(input, "Package") @@ -198,7 +198,7 @@ func (p *Package) MatchesArchitecture(arch string) bool { } // MatchesDependency checks whether package matches specified dependency -func (p *Package) MatchesDependency(dep Dependency, allMatches bool) bool { +func (p *Package) MatchesDependency(dep Dependency) bool { if dep.Pkg != p.Name { return false } @@ -215,12 +215,7 @@ func (p *Package) MatchesDependency(dep Dependency, allMatches bool) bool { switch dep.Relation { case VersionEqual: - if allMatches { - rn := CompareVersions(p.Version, dep.NextVersion()) - return r+rn == 0 || r == 0 - } else { - return r == 0 - } + return r == 0 case VersionLess: return r < 0 case VersionGreater: diff --git a/deb/package_test.go b/deb/package_test.go index 3d37bd8e..9f967ec7 100644 --- a/deb/package_test.go +++ b/deb/package_test.go @@ -90,16 +90,16 @@ func (s *PackageSuite) TestKey(c *C) { c.Check(p.Key(""), DeepEquals, []byte("Pi386 alien-arena-common 7.40-2 c8901eedd79ac51b")) c.Check(p.Key("xD"), DeepEquals, []byte("xDPi386 alien-arena-common 7.40-2 c8901eedd79ac51b")) - p.V06Plus = false - c.Check(p.Key(""), DeepEquals, []byte("Pi386 alien-arena-common 7.40-2")) - c.Check(p.Key("xD"), DeepEquals, []byte("xDPi386 alien-arena-common 7.40-2")) + p.V06Plus = false + c.Check(p.Key(""), DeepEquals, []byte("Pi386 alien-arena-common 7.40-2")) + c.Check(p.Key("xD"), DeepEquals, []byte("xDPi386 alien-arena-common 7.40-2")) } func (s *PackageSuite) TestShortKey(c *C) { - p := NewPackageFromControlFile(s.stanza) + p := NewPackageFromControlFile(s.stanza) - c.Check(p.ShortKey(""), DeepEquals, []byte("Pi386 alien-arena-common 7.40-2")) - c.Check(p.ShortKey("xD"), DeepEquals, []byte("xDPi386 alien-arena-common 7.40-2")) + c.Check(p.ShortKey(""), DeepEquals, []byte("Pi386 alien-arena-common 7.40-2")) + c.Check(p.ShortKey("xD"), DeepEquals, []byte("xDPi386 alien-arena-common 7.40-2")) } func (s *PackageSuite) TestStanza(c *C) { @@ -172,44 +172,41 @@ func (s *PackageSuite) TestMatchesDependency(c *C) { p := NewPackageFromControlFile(s.stanza) // exact match - c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionEqual, Version: "7.40-2"}, false), Equals, true) + c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionEqual, Version: "7.40-2"}), 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) + c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionEqual, Version: "7.40"}), Equals, false) // different name - c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena", Architecture: "i386", Relation: VersionEqual, Version: "7.40-2"}, false), Equals, false) + c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena", Architecture: "i386", Relation: VersionEqual, Version: "7.40-2"}), Equals, false) // different version - c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionEqual, Version: "7.40-3"}, false), Equals, false) + c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "i386", Relation: VersionEqual, Version: "7.40-3"}), Equals, false) // different arch - c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "amd64", Relation: VersionEqual, Version: "7.40-2"}, false), Equals, false) + c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "amd64", Relation: VersionEqual, Version: "7.40-2"}), Equals, false) // empty arch - c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "", Relation: VersionEqual, Version: "7.40-2"}, false), Equals, true) + c.Check(p.MatchesDependency(Dependency{Pkg: "alien-arena-common", Architecture: "", Relation: VersionEqual, Version: "7.40-2"}), Equals, true) // version don't care - 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: VersionDontCare, Version: ""}), Equals, true) // > - 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"}, 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-1"}), Equals, true) // < - 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"}, 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-3"}), 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"}, false), Equals, false) + 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-3"}), Equals, false) // <= - 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"}, 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-1"}), Equals, false) } func (s *PackageSuite) TestGetDependencies(c *C) { From 9af10bc422a5eefd56fb8e57d55faeba00957662 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 10 Jul 2014 00:43:42 +0400 Subject: [PATCH 6/8] Refactoring: simplification. #70 --- deb/list.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/deb/list.go b/deb/list.go index 1dcc2494..1c5058f2 100644 --- a/deb/list.go +++ b/deb/list.go @@ -334,13 +334,11 @@ func (l *PackageList) PrepareIndex() { } // Search searches package index for specified package -func (l *PackageList) Search(dep Dependency, allMatches bool) []*Package { +func (l *PackageList) Search(dep Dependency, allMatches bool) (searchResults []*Package) { if !l.indexed { panic("list not indexed, can't search") } - searchResults := []*Package{} - if dep.Relation == VersionDontCare { for _, p := range l.providesIndex[dep.Pkg] { if p.MatchesArchitecture(dep.Architecture) { @@ -352,7 +350,7 @@ func (l *PackageList) Search(dep Dependency, allMatches bool) []*Package { } } if len(searchResults) != 0 { - return searchResults + return } } @@ -371,11 +369,7 @@ func (l *PackageList) Search(dep Dependency, allMatches bool) []*Package { i++ } - if len(searchResults) != 0 { - return searchResults - } - - return nil + return } // Filter filters package index by specified queries (ORed together), possibly pulling dependencies From 2a9b2f87f99e26ccf79eac3b6e42a990692a2dd2 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 10 Jul 2014 00:48:24 +0400 Subject: [PATCH 7/8] Update man page. #70 --- man/aptly.1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/man/aptly.1 b/man/aptly.1 index 6c336482..62398f77 100644 --- a/man/aptly.1 +++ b/man/aptly.1 @@ -603,6 +603,10 @@ $ aptly snapshot pull wheezy\-main wheezy\-backports wheezy\-new\-xorg xorg\-ser Options: . .TP +\-\fBall\-matches\fR=false +pull all the packages that satisfy the dependency version requirements +. +.TP \-\fBdry\-run\fR=false don\(cqt create destination snapshot, just show what would be pulled . From a7cb40ee7a5ca719a9f97ea4eddea39785d96a7b Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 10 Jul 2014 00:55:53 +0400 Subject: [PATCH 8/8] System tests for aptly snapshot pull -all-matches. #70 --- system/t05_snapshot/PullSnapshot13Test_gold | 164 ++++++++++++++++++++ system/t05_snapshot/PullSnapshot14Test_gold | 62 ++++++++ system/t05_snapshot/pull.py | 24 +++ 3 files changed, 250 insertions(+) create mode 100644 system/t05_snapshot/PullSnapshot13Test_gold create mode 100644 system/t05_snapshot/PullSnapshot14Test_gold diff --git a/system/t05_snapshot/PullSnapshot13Test_gold b/system/t05_snapshot/PullSnapshot13Test_gold new file mode 100644 index 00000000..14ef34fc --- /dev/null +++ b/system/t05_snapshot/PullSnapshot13Test_gold @@ -0,0 +1,164 @@ +Dependencies would be pulled into snapshot: + [empty]: Created as empty +from snapshot: + [sensu]: Snapshot from mirror [sensu]: http://repos.sensuapp.org/apt/ sensu +and result would be saved as new snapshot destination. +Loading packages (154)... +Building indexes... +[+] sensu_0.12.6-5_amd64 added +[+] sensu_0.12.6-4_amd64 added +[+] sensu_0.12.6-3_amd64 added +[+] sensu_0.12.6-2_amd64 added +[+] sensu_0.12.6-1_amd64 added +[+] sensu_0.12.5-1_amd64 added +[+] sensu_0.12.4-1_amd64 added +[+] sensu_0.12.3-1_amd64 added +[+] sensu_0.12.2-1_amd64 added +[+] sensu_0.12.1-1_amd64 added +[+] sensu_0.12.0-1_amd64 added +[+] sensu_0.11.3-1_amd64 added +[+] sensu_0.11.1-1_amd64 added +[+] sensu_0.11.0.beta.4-1_amd64 added +[+] sensu_0.11.0.beta.3-1_amd64 added +[+] sensu_0.11.0.beta.2-1_amd64 added +[+] sensu_0.11.0.beta.1-1_amd64 added +[+] sensu_0.11.0.beta-1_amd64 added +[+] sensu_0.11.0-1_amd64 added +[+] sensu_0.10.2-1_amd64 added +[+] sensu_0.10.1-1_amd64 added +[+] sensu_0.10.0-2_amd64 added +[+] sensu_0.10.0-1_amd64 added +[+] sensu_0.9.13.beta.1-1_amd64 added +[+] sensu_0.9.13.beta-2_amd64 added +[+] sensu_0.9.13.beta-1_amd64 added +[+] sensu_0.9.13-1_amd64 added +[+] sensu_0.9.12.beta.6-2_amd64 added +[+] sensu_0.9.12.beta.6-1_amd64 added +[+] sensu_0.9.12.beta.5-5_amd64 added +[+] sensu_0.9.12.beta.5-4_amd64 added +[+] sensu_0.9.12.beta.5-3_amd64 added +[+] sensu_0.9.12.beta.5-2_amd64 added +[+] sensu_0.9.12.beta.5-1_amd64 added +[+] sensu_0.9.12.beta.4-1_amd64 added +[+] sensu_0.9.12.beta.3-3_amd64 added +[+] sensu_0.9.12.beta.3-2_amd64 added +[+] sensu_0.9.12.beta.3-1_amd64 added +[+] sensu_0.9.12.beta.2-1_amd64 added +[+] sensu_0.9.12.beta.1-1_amd64 added +[+] sensu_0.9.12.beta-1_amd64 added +[+] sensu_0.9.12-3_amd64 added +[+] sensu_0.9.12-2_amd64 added +[+] sensu_0.9.12-1_amd64 added +[+] sensu_0.9.11-1_amd64 added +[+] sensu_0.9.10-1_amd64 added +[+] sensu_0.9.9.beta.4-1_amd64 added +[+] sensu_0.9.9.beta.3-2_amd64 added +[+] sensu_0.9.9.beta.3-1_amd64 added +[+] sensu_0.9.9.beta.2-1_amd64 added +[+] sensu_0.9.9.beta.1-1_amd64 added +[+] sensu_0.9.9.beta-1_amd64 added +[+] sensu_0.9.9-1_amd64 added +[+] sensu_0.9.8.beta.4-1_amd64 added +[+] sensu_0.9.8.beta.3-1_amd64 added +[+] sensu_0.9.8.beta.2-1_amd64 added +[+] sensu_0.9.8.beta.1-1_amd64 added +[+] sensu_0.9.8.beta-1_amd64 added +[+] sensu_0.9.8-1_amd64 added +[+] sensu_0.9.7.beta.4-1_amd64 added +[+] sensu_0.9.7.beta.3-1_amd64 added +[+] sensu_0.9.7.beta.2-1_amd64 added +[+] sensu_0.9.7.beta.1-1_amd64 added +[+] sensu_0.9.7.beta-1_amd64 added +[+] sensu_0.9.7-1_amd64 added +[+] sensu_0.9.6.beta.7-1_amd64 added +[+] sensu_0.9.6.beta.6-1_amd64 added +[+] sensu_0.9.6.beta.3-1_amd64 added +[+] sensu_0.9.6.beta.2-1_amd64 added +[+] sensu_0.9.6-4_amd64 added +[+] sensu_0.9.6-3_amd64 added +[+] sensu_0.9.6-2_amd64 added +[+] sensu_0.9.6-1_amd64 added +[+] sensu_0.9.5-36_amd64 added +[+] sensu_0.9.5-35_amd64 added +[+] sensu_0.9.5-34_amd64 added +[+] sensu_0.9.5-30_amd64 added +[+] sensu_0.12.6-5_i386 added +[+] sensu_0.12.6-4_i386 added +[+] sensu_0.12.6-3_i386 added +[+] sensu_0.12.6-2_i386 added +[+] sensu_0.12.6-1_i386 added +[+] sensu_0.12.5-1_i386 added +[+] sensu_0.12.4-1_i386 added +[+] sensu_0.12.3-1_i386 added +[+] sensu_0.12.2-1_i386 added +[+] sensu_0.12.1-1_i386 added +[+] sensu_0.12.0-1_i386 added +[+] sensu_0.11.3-1_i386 added +[+] sensu_0.11.1-1_i386 added +[+] sensu_0.11.0.beta.4-1_i386 added +[+] sensu_0.11.0.beta.3-1_i386 added +[+] sensu_0.11.0.beta.2-1_i386 added +[+] sensu_0.11.0.beta.1-1_i386 added +[+] sensu_0.11.0.beta-1_i386 added +[+] sensu_0.11.0-1_i386 added +[+] sensu_0.10.2-1_i386 added +[+] sensu_0.10.1-1_i386 added +[+] sensu_0.10.0-2_i386 added +[+] sensu_0.10.0-1_i386 added +[+] sensu_0.9.13.beta.1-1_i386 added +[+] sensu_0.9.13.beta-2_i386 added +[+] sensu_0.9.13.beta-1_i386 added +[+] sensu_0.9.13-1_i386 added +[+] sensu_0.9.12.beta.6-2_i386 added +[+] sensu_0.9.12.beta.6-1_i386 added +[+] sensu_0.9.12.beta.5-5_i386 added +[+] sensu_0.9.12.beta.5-4_i386 added +[+] sensu_0.9.12.beta.5-3_i386 added +[+] sensu_0.9.12.beta.5-2_i386 added +[+] sensu_0.9.12.beta.5-1_i386 added +[+] sensu_0.9.12.beta.4-1_i386 added +[+] sensu_0.9.12.beta.3-3_i386 added +[+] sensu_0.9.12.beta.3-2_i386 added +[+] sensu_0.9.12.beta.3-1_i386 added +[+] sensu_0.9.12.beta.2-1_i386 added +[+] sensu_0.9.12.beta.1-1_i386 added +[+] sensu_0.9.12.beta-1_i386 added +[+] sensu_0.9.12-3_i386 added +[+] sensu_0.9.12-2_i386 added +[+] sensu_0.9.12-1_i386 added +[+] sensu_0.9.11-1_i386 added +[+] sensu_0.9.10-1_i386 added +[+] sensu_0.9.9.beta.4-1_i386 added +[+] sensu_0.9.9.beta.3-2_i386 added +[+] sensu_0.9.9.beta.3-1_i386 added +[+] sensu_0.9.9.beta.2-1_i386 added +[+] sensu_0.9.9.beta.1-1_i386 added +[+] sensu_0.9.9.beta-1_i386 added +[+] sensu_0.9.9-1_i386 added +[+] sensu_0.9.8.beta.4-1_i386 added +[+] sensu_0.9.8.beta.3-1_i386 added +[+] sensu_0.9.8.beta.2-1_i386 added +[+] sensu_0.9.8.beta.1-1_i386 added +[+] sensu_0.9.8.beta-1_i386 added +[+] sensu_0.9.8-1_i386 added +[+] sensu_0.9.7.beta.4-1_i386 added +[+] sensu_0.9.7.beta.3-1_i386 added +[+] sensu_0.9.7.beta.2-1_i386 added +[+] sensu_0.9.7.beta.1-1_i386 added +[+] sensu_0.9.7.beta-1_i386 added +[+] sensu_0.9.7-1_i386 added +[+] sensu_0.9.6.beta.7-1_i386 added +[+] sensu_0.9.6.beta.6-1_i386 added +[+] sensu_0.9.6.beta.3-1_i386 added +[+] sensu_0.9.6.beta.2-1_i386 added +[+] sensu_0.9.6-4_i386 added +[+] sensu_0.9.6-3_i386 added +[+] sensu_0.9.6-2_i386 added +[+] sensu_0.9.6-1_i386 added +[+] sensu_0.9.5-36_i386 added +[+] sensu_0.9.5-35_i386 added +[+] sensu_0.9.5-34_i386 added +[+] sensu_0.9.5-32_i386 added + +Snapshot destination successfully created. +You can run 'aptly publish snapshot destination' to publish snapshot as Debian repository. diff --git a/system/t05_snapshot/PullSnapshot14Test_gold b/system/t05_snapshot/PullSnapshot14Test_gold new file mode 100644 index 00000000..21d64d38 --- /dev/null +++ b/system/t05_snapshot/PullSnapshot14Test_gold @@ -0,0 +1,62 @@ +Dependencies would be pulled into snapshot: + [empty]: Created as empty +from snapshot: + [sensu]: Snapshot from mirror [sensu]: http://repos.sensuapp.org/apt/ sensu +and result would be saved as new snapshot destination. +Loading packages (154)... +Building indexes... +[+] sensu_0.12.6-5_amd64 added +[+] sensu_0.12.6-4_amd64 added +[+] sensu_0.12.6-3_amd64 added +[+] sensu_0.12.6-2_amd64 added +[+] sensu_0.12.6-1_amd64 added +[+] sensu_0.12.5-1_amd64 added +[+] sensu_0.12.4-1_amd64 added +[+] sensu_0.12.3-1_amd64 added +[+] sensu_0.12.2-1_amd64 added +[+] sensu_0.12.1-1_amd64 added +[+] sensu_0.12.0-1_amd64 added +[-] sensu_0.12.6-5_amd64 removed +[-] sensu_0.12.6-4_amd64 removed +[-] sensu_0.12.6-3_amd64 removed +[-] sensu_0.12.6-2_amd64 removed +[-] sensu_0.12.6-1_amd64 removed +[-] sensu_0.12.5-1_amd64 removed +[-] sensu_0.12.4-1_amd64 removed +[-] sensu_0.12.3-1_amd64 removed +[-] sensu_0.12.2-1_amd64 removed +[-] sensu_0.12.1-1_amd64 removed +[-] sensu_0.12.0-1_amd64 removed +[+] sensu_0.9.5-36_amd64 added +[+] sensu_0.9.5-35_amd64 added +[+] sensu_0.9.5-34_amd64 added +[+] sensu_0.9.5-30_amd64 added +[+] sensu_0.12.6-5_i386 added +[+] sensu_0.12.6-4_i386 added +[+] sensu_0.12.6-3_i386 added +[+] sensu_0.12.6-2_i386 added +[+] sensu_0.12.6-1_i386 added +[+] sensu_0.12.5-1_i386 added +[+] sensu_0.12.4-1_i386 added +[+] sensu_0.12.3-1_i386 added +[+] sensu_0.12.2-1_i386 added +[+] sensu_0.12.1-1_i386 added +[+] sensu_0.12.0-1_i386 added +[-] sensu_0.12.6-5_i386 removed +[-] sensu_0.12.6-4_i386 removed +[-] sensu_0.12.6-3_i386 removed +[-] sensu_0.12.6-2_i386 removed +[-] sensu_0.12.6-1_i386 removed +[-] sensu_0.12.5-1_i386 removed +[-] sensu_0.12.4-1_i386 removed +[-] sensu_0.12.3-1_i386 removed +[-] sensu_0.12.2-1_i386 removed +[-] sensu_0.12.1-1_i386 removed +[-] sensu_0.12.0-1_i386 removed +[+] sensu_0.9.5-36_i386 added +[+] sensu_0.9.5-35_i386 added +[+] sensu_0.9.5-34_i386 added +[+] sensu_0.9.5-32_i386 added + +Snapshot destination successfully created. +You can run 'aptly publish snapshot destination' to publish snapshot as Debian repository. diff --git a/system/t05_snapshot/pull.py b/system/t05_snapshot/pull.py index 28bab575..69229366 100644 --- a/system/t05_snapshot/pull.py +++ b/system/t05_snapshot/pull.py @@ -207,3 +207,27 @@ class PullSnapshot12Test(BaseTest): "aptly snapshot create sensu from mirror sensu", ] runCmd = "aptly snapshot pull -architectures=amd64,i386 empty sensu destination sensu" + + +class PullSnapshot13Test(BaseTest): + """ + pull snapshot: pull all versions + """ + fixtureDB = True + fixtureCmds = [ + "aptly snapshot create empty empty", + "aptly snapshot create sensu from mirror sensu", + ] + runCmd = "aptly snapshot pull -architectures=amd64,i386 -all-matches empty sensu destination sensu" + + +class PullSnapshot14Test(BaseTest): + """ + pull snapshot: pull with query + """ + fixtureDB = True + fixtureCmds = [ + "aptly snapshot create empty empty", + "aptly snapshot create sensu from mirror sensu", + ] + runCmd = "aptly snapshot pull -architectures=amd64,i386 -all-matches empty sensu destination 'sensu (>0.12)' 'sensu (<0.9.6)'"