mirror of
https://github.com/mudler/luet.git
synced 2025-09-01 15:18:28 +00:00
Add support for Package provides
Add "provides" field in packages (which affect both runtime and buildtime deps). It replaces all the occurences in the deptree before solving, actually allowing to swap packages and provide virtuals. Along with a mechanism for package rename #25.
This commit is contained in:
committed by
Ettore Di Giacinto
parent
0627b03121
commit
15250bd991
@@ -441,6 +441,7 @@ func (cs *LuetCompiler) ComputeDepTree(p CompilationSpec) (solver.PackagesAssert
|
||||
}
|
||||
|
||||
dependencies := solution.Order(cs.Database, p.GetPackage().GetFingerPrint())
|
||||
|
||||
assertions := solver.PackagesAssertions{}
|
||||
for _, assertion := range dependencies { //highly dependent on the order
|
||||
if assertion.Value {
|
||||
|
@@ -316,6 +316,90 @@ var _ = Describe("Compiler", func() {
|
||||
Expect(helpers.Exists(spec.Rel("extra-layer-0.1.package.tar"))).To(BeTrue())
|
||||
})
|
||||
|
||||
It("Compiles with provides support", func() {
|
||||
generalRecipe := tree.NewCompilerRecipe(pkg.NewInMemoryDatabase(false))
|
||||
tmpdir, err := ioutil.TempDir("", "package")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer os.RemoveAll(tmpdir) // clean up
|
||||
|
||||
err = generalRecipe.Load("../../tests/fixtures/provides")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3))
|
||||
|
||||
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase())
|
||||
|
||||
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "d", Category: "test", Version: "1.0"})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
// err = generalRecipe.Tree().ResolveDeps(3)
|
||||
// Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
spec.SetOutputPath(tmpdir)
|
||||
|
||||
artifacts, errs := compiler.CompileParallel(1, false, NewLuetCompilationspecs(spec))
|
||||
Expect(errs).To(BeNil())
|
||||
Expect(len(artifacts)).To(Equal(1))
|
||||
Expect(len(artifacts[0].GetDependencies())).To(Equal(1))
|
||||
|
||||
for _, artifact := range artifacts {
|
||||
Expect(helpers.Exists(artifact.GetPath())).To(BeTrue())
|
||||
Expect(helpers.Untar(artifact.GetPath(), tmpdir, false)).ToNot(HaveOccurred())
|
||||
}
|
||||
Expect(helpers.Untar(spec.Rel("c-test-1.0.package.tar"), tmpdir, false)).ToNot(HaveOccurred())
|
||||
|
||||
Expect(helpers.Exists(spec.Rel("d"))).To(BeTrue())
|
||||
Expect(helpers.Exists(spec.Rel("dd"))).To(BeTrue())
|
||||
Expect(helpers.Exists(spec.Rel("c"))).To(BeTrue())
|
||||
Expect(helpers.Exists(spec.Rel("cd"))).To(BeTrue())
|
||||
|
||||
Expect(helpers.Exists(spec.Rel("d-test-1.0.metadata.yaml"))).To(BeTrue())
|
||||
|
||||
Expect(helpers.Exists(spec.Rel("c-test-1.0.metadata.yaml"))).To(BeTrue())
|
||||
})
|
||||
|
||||
It("Compiles with provides and selectors support", func() {
|
||||
// Same test as before, but fixtures differs
|
||||
generalRecipe := tree.NewCompilerRecipe(pkg.NewInMemoryDatabase(false))
|
||||
tmpdir, err := ioutil.TempDir("", "package")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer os.RemoveAll(tmpdir) // clean up
|
||||
|
||||
err = generalRecipe.Load("../../tests/fixtures/provides_selector")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3))
|
||||
|
||||
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase())
|
||||
|
||||
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "d", Category: "test", Version: "1.0"})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
// err = generalRecipe.Tree().ResolveDeps(3)
|
||||
// Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
spec.SetOutputPath(tmpdir)
|
||||
|
||||
artifacts, errs := compiler.CompileParallel(1, false, NewLuetCompilationspecs(spec))
|
||||
Expect(errs).To(BeNil())
|
||||
Expect(len(artifacts)).To(Equal(1))
|
||||
Expect(len(artifacts[0].GetDependencies())).To(Equal(1))
|
||||
|
||||
for _, artifact := range artifacts {
|
||||
Expect(helpers.Exists(artifact.GetPath())).To(BeTrue())
|
||||
Expect(helpers.Untar(artifact.GetPath(), tmpdir, false)).ToNot(HaveOccurred())
|
||||
}
|
||||
Expect(helpers.Untar(spec.Rel("c-test-1.0.package.tar"), tmpdir, false)).ToNot(HaveOccurred())
|
||||
|
||||
Expect(helpers.Exists(spec.Rel("d"))).To(BeTrue())
|
||||
Expect(helpers.Exists(spec.Rel("dd"))).To(BeTrue())
|
||||
Expect(helpers.Exists(spec.Rel("c"))).To(BeTrue())
|
||||
Expect(helpers.Exists(spec.Rel("cd"))).To(BeTrue())
|
||||
|
||||
Expect(helpers.Exists(spec.Rel("d-test-1.0.metadata.yaml"))).To(BeTrue())
|
||||
|
||||
Expect(helpers.Exists(spec.Rel("c-test-1.0.metadata.yaml"))).To(BeTrue())
|
||||
})
|
||||
It("Compiles revdeps", func() {
|
||||
generalRecipe := tree.NewCompilerRecipe(pkg.NewInMemoryDatabase(false))
|
||||
tmpdir, err := ioutil.TempDir("", "revdep")
|
||||
|
@@ -34,7 +34,8 @@ import (
|
||||
|
||||
type BoltDatabase struct {
|
||||
sync.Mutex
|
||||
Path string
|
||||
Path string
|
||||
ProvidesDatabase map[string]map[string]Package
|
||||
}
|
||||
|
||||
func NewBoltDatabase(path string) PackageDatabase {
|
||||
@@ -42,7 +43,7 @@ func NewBoltDatabase(path string) PackageDatabase {
|
||||
// BoltInstance = &BoltDatabase{Path: path}
|
||||
// }
|
||||
//return BoltInstance, nil
|
||||
return &BoltDatabase{Path: path}
|
||||
return &BoltDatabase{Path: path, ProvidesDatabase: map[string]map[string]Package{}}
|
||||
}
|
||||
|
||||
func (db *BoltDatabase) Get(s string) (string, error) {
|
||||
@@ -85,6 +86,11 @@ func (db *BoltDatabase) Retrieve(ID string) ([]byte, error) {
|
||||
}
|
||||
|
||||
func (db *BoltDatabase) FindPackage(tofind Package) (Package, error) {
|
||||
// Provides: Return the replaced package here
|
||||
if provided, err := db.getProvide(tofind); err == nil {
|
||||
return provided, nil
|
||||
}
|
||||
|
||||
p := &DefaultPackage{}
|
||||
bolt, err := storm.Open(db.Path, storm.BoltOptions(0600, &bbolt.Options{Timeout: 30 * time.Second}))
|
||||
if err != nil {
|
||||
@@ -196,9 +202,62 @@ func (db *BoltDatabase) CreatePackage(p Package) (string, error) {
|
||||
return "", errors.Wrap(err, "Error saving package to "+db.Path)
|
||||
}
|
||||
|
||||
// Create extra cache between package -> []versions
|
||||
db.Lock()
|
||||
defer db.Unlock()
|
||||
// TODO: Replace with a bolt implementation (and not in memory)
|
||||
// Provides: Store package provides, we will reuse this when walking deps
|
||||
for _, provide := range dp.Provides {
|
||||
if _, ok := db.ProvidesDatabase[provide.GetPackageName()]; !ok {
|
||||
db.ProvidesDatabase[provide.GetPackageName()] = make(map[string]Package)
|
||||
|
||||
}
|
||||
|
||||
db.ProvidesDatabase[provide.GetPackageName()][provide.GetVersion()] = p
|
||||
}
|
||||
|
||||
return strconv.Itoa(dp.ID), err
|
||||
}
|
||||
|
||||
// Dup from memory implementation
|
||||
func (db *BoltDatabase) getProvide(p Package) (Package, error) {
|
||||
db.Lock()
|
||||
pa, ok := db.ProvidesDatabase[p.GetPackageName()][p.GetVersion()]
|
||||
if !ok {
|
||||
versions, ok := db.ProvidesDatabase[p.GetPackageName()]
|
||||
db.Unlock()
|
||||
|
||||
if !ok {
|
||||
return nil, errors.New("No versions found for package")
|
||||
}
|
||||
|
||||
for ve, _ := range versions {
|
||||
|
||||
v, err := version.NewVersion(p.GetVersion())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
constraints, err := version.NewConstraint(ve)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if constraints.Check(v) {
|
||||
pa, ok := db.ProvidesDatabase[p.GetPackageName()][ve]
|
||||
if !ok {
|
||||
return nil, errors.New("No versions found for package")
|
||||
}
|
||||
return pa, nil //pick the first (we shouldn't have providers that are conflicting)
|
||||
// TODO: A find dbcall here would recurse, but would give chance to have providers of providers
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("No package provides this")
|
||||
}
|
||||
db.Unlock()
|
||||
return db.FindPackage(pa)
|
||||
}
|
||||
|
||||
func (db *BoltDatabase) Clean() error {
|
||||
db.Lock()
|
||||
defer db.Unlock()
|
||||
@@ -298,6 +357,10 @@ func (db *BoltDatabase) FindPackageCandidate(p Package) (Package, error) {
|
||||
// FindPackages return the list of the packages beloging to cat/name (any versions in requested range)
|
||||
// FIXME: Optimize, see inmemorydb
|
||||
func (db *BoltDatabase) FindPackages(p Package) ([]Package, error) {
|
||||
// Provides: Treat as the replaced package here
|
||||
if provided, err := db.getProvide(p); err == nil {
|
||||
p = provided
|
||||
}
|
||||
var versionsInWorld []Package
|
||||
for _, w := range db.World() {
|
||||
if w.GetName() != p.GetName() || w.GetCategory() != p.GetCategory() {
|
||||
|
@@ -25,27 +25,30 @@ import (
|
||||
)
|
||||
|
||||
var DBInMemoryInstance = &InMemoryDatabase{
|
||||
Mutex: &sync.Mutex{},
|
||||
FileDatabase: map[string][]string{},
|
||||
Database: map[string]string{},
|
||||
CacheNoVersion: map[string]map[string]interface{}{},
|
||||
Mutex: &sync.Mutex{},
|
||||
FileDatabase: map[string][]string{},
|
||||
Database: map[string]string{},
|
||||
CacheNoVersion: map[string]map[string]interface{}{},
|
||||
ProvidesDatabase: map[string]map[string]Package{},
|
||||
}
|
||||
|
||||
type InMemoryDatabase struct {
|
||||
*sync.Mutex
|
||||
Database map[string]string
|
||||
FileDatabase map[string][]string
|
||||
CacheNoVersion map[string]map[string]interface{}
|
||||
Database map[string]string
|
||||
FileDatabase map[string][]string
|
||||
CacheNoVersion map[string]map[string]interface{}
|
||||
ProvidesDatabase map[string]map[string]Package
|
||||
}
|
||||
|
||||
func NewInMemoryDatabase(singleton bool) PackageDatabase {
|
||||
// In memoryDB is a singleton
|
||||
if !singleton {
|
||||
return &InMemoryDatabase{
|
||||
Mutex: &sync.Mutex{},
|
||||
FileDatabase: map[string][]string{},
|
||||
Database: map[string]string{},
|
||||
CacheNoVersion: map[string]map[string]interface{}{},
|
||||
Mutex: &sync.Mutex{},
|
||||
FileDatabase: map[string][]string{},
|
||||
Database: map[string]string{},
|
||||
CacheNoVersion: map[string]map[string]interface{}{},
|
||||
ProvidesDatabase: map[string]map[string]Package{},
|
||||
}
|
||||
}
|
||||
return DBInMemoryInstance
|
||||
@@ -142,6 +145,17 @@ func (db *InMemoryDatabase) CreatePackage(p Package) (string, error) {
|
||||
// Create extra cache between package -> []versions
|
||||
db.Lock()
|
||||
defer db.Unlock()
|
||||
|
||||
// Provides: Store package provides, we will reuse this when walking deps
|
||||
for _, provide := range pd.Provides {
|
||||
if _, ok := db.ProvidesDatabase[provide.GetPackageName()]; !ok {
|
||||
db.ProvidesDatabase[provide.GetPackageName()] = make(map[string]Package)
|
||||
|
||||
}
|
||||
|
||||
db.ProvidesDatabase[provide.GetPackageName()][provide.GetVersion()] = p
|
||||
}
|
||||
|
||||
_, ok = db.CacheNoVersion[p.GetPackageName()]
|
||||
if !ok {
|
||||
db.CacheNoVersion[p.GetPackageName()] = make(map[string]interface{})
|
||||
@@ -151,6 +165,43 @@ func (db *InMemoryDatabase) CreatePackage(p Package) (string, error) {
|
||||
return ID, nil
|
||||
}
|
||||
|
||||
func (db *InMemoryDatabase) getProvide(p Package) (Package, error) {
|
||||
db.Lock()
|
||||
pa, ok := db.ProvidesDatabase[p.GetPackageName()][p.GetVersion()]
|
||||
if !ok {
|
||||
versions, ok := db.ProvidesDatabase[p.GetPackageName()]
|
||||
db.Unlock()
|
||||
|
||||
if !ok {
|
||||
return nil, errors.New("No versions found for package")
|
||||
}
|
||||
|
||||
for ve, _ := range versions {
|
||||
|
||||
v, err := version.NewVersion(p.GetVersion())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
constraints, err := version.NewConstraint(ve)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if constraints.Check(v) {
|
||||
pa, ok := db.ProvidesDatabase[p.GetPackageName()][ve]
|
||||
if !ok {
|
||||
return nil, errors.New("No versions found for package")
|
||||
}
|
||||
return pa, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("No package provides this")
|
||||
}
|
||||
db.Unlock()
|
||||
return db.FindPackage(pa)
|
||||
}
|
||||
|
||||
func (db *InMemoryDatabase) encodePackage(p Package) (string, string, error) {
|
||||
pd, ok := p.(*DefaultPackage)
|
||||
if !ok {
|
||||
@@ -167,6 +218,12 @@ func (db *InMemoryDatabase) encodePackage(p Package) (string, string, error) {
|
||||
}
|
||||
|
||||
func (db *InMemoryDatabase) FindPackage(p Package) (Package, error) {
|
||||
|
||||
// Provides: Return the replaced package here
|
||||
if provided, err := db.getProvide(p); err == nil {
|
||||
return provided, nil
|
||||
}
|
||||
|
||||
return db.GetPackage(p.GetFingerPrint())
|
||||
}
|
||||
|
||||
@@ -189,6 +246,11 @@ func (db *InMemoryDatabase) FindPackageVersions(p Package) ([]Package, error) {
|
||||
|
||||
// FindPackages return the list of the packages beloging to cat/name (any versions in requested range)
|
||||
func (db *InMemoryDatabase) FindPackages(p Package) ([]Package, error) {
|
||||
|
||||
// Provides: Treat as the replaced package here
|
||||
if provided, err := db.getProvide(p); err == nil {
|
||||
p = provided
|
||||
}
|
||||
versions, ok := db.CacheNoVersion[p.GetPackageName()]
|
||||
if !ok {
|
||||
return nil, errors.New("No versions found for package")
|
||||
|
@@ -76,6 +76,31 @@ var _ = Describe("Database", func() {
|
||||
Expect(pack).To(Equal(a3))
|
||||
|
||||
})
|
||||
|
||||
It("Provides replaces definitions", func() {
|
||||
db := NewInMemoryDatabase(false)
|
||||
a := NewPackage("A", "1.0", []*DefaultPackage{}, []*DefaultPackage{})
|
||||
a1 := NewPackage("A", "1.1", []*DefaultPackage{}, []*DefaultPackage{})
|
||||
a3 := NewPackage("A", "1.3", []*DefaultPackage{}, []*DefaultPackage{})
|
||||
|
||||
a3.SetProvides([]*DefaultPackage{{Name: "A", Category: "", Version: "1.0"}})
|
||||
Expect(a3.GetProvides()).To(Equal([]*DefaultPackage{{Name: "A", Category: "", Version: "1.0"}}))
|
||||
|
||||
_, err := db.CreatePackage(a)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
_, err = db.CreatePackage(a1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
_, err = db.CreatePackage(a3)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
s := NewPackage("A", "1.0", []*DefaultPackage{}, []*DefaultPackage{})
|
||||
|
||||
pack, err := db.FindPackage(s)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pack).To(Equal(a3))
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
@@ -46,6 +46,9 @@ type Package interface {
|
||||
Conflicts([]*DefaultPackage) Package
|
||||
Revdeps(PackageDatabase) []Package
|
||||
|
||||
GetProvides() []*DefaultPackage
|
||||
SetProvides([]*DefaultPackage) Package
|
||||
|
||||
GetRequires() []*DefaultPackage
|
||||
GetConflicts() []*DefaultPackage
|
||||
Expand(PackageDatabase) ([]Package, error)
|
||||
@@ -132,6 +135,7 @@ type DefaultPackage struct {
|
||||
PackageRequires []*DefaultPackage `json:"requires"` // Affects YAML field names too.
|
||||
PackageConflicts []*DefaultPackage `json:"conflicts"` // Affects YAML field names too.
|
||||
IsSet bool `json:"set"` // Affects YAML field names too.
|
||||
Provides []*DefaultPackage `json:"provides"` // Affects YAML field names too.
|
||||
|
||||
// TODO: Annotations?
|
||||
|
||||
@@ -270,7 +274,13 @@ func (p *DefaultPackage) SetCategory(s string) {
|
||||
func (p *DefaultPackage) GetUses() []string {
|
||||
return p.UseFlags
|
||||
}
|
||||
|
||||
func (p *DefaultPackage) GetProvides() []*DefaultPackage {
|
||||
return p.Provides
|
||||
}
|
||||
func (p *DefaultPackage) SetProvides(req []*DefaultPackage) Package {
|
||||
p.Provides = req
|
||||
return p
|
||||
}
|
||||
func (p *DefaultPackage) GetRequires() []*DefaultPackage {
|
||||
return p.PackageRequires
|
||||
}
|
||||
@@ -436,7 +446,11 @@ func (pack *DefaultPackage) BuildFormula(definitiondb PackageDatabase, db Packag
|
||||
var formulas []bf.Formula
|
||||
for _, requiredDef := range p.GetRequires() {
|
||||
required, err := definitiondb.FindPackage(requiredDef)
|
||||
if err != nil {
|
||||
if err != nil || requiredDef.IsSelector() {
|
||||
if err == nil {
|
||||
requiredDef = required.(*DefaultPackage)
|
||||
}
|
||||
|
||||
packages, err := definitiondb.FindPackages(requiredDef)
|
||||
if err != nil || len(packages) == 0 {
|
||||
required = requiredDef
|
||||
@@ -515,8 +529,11 @@ func (pack *DefaultPackage) BuildFormula(definitiondb PackageDatabase, db Packag
|
||||
|
||||
for _, requiredDef := range p.GetConflicts() {
|
||||
required, err := definitiondb.FindPackage(requiredDef)
|
||||
if err != nil {
|
||||
packages, err := requiredDef.Expand(definitiondb)
|
||||
if err != nil || requiredDef.IsSelector() {
|
||||
if err == nil {
|
||||
requiredDef = required.(*DefaultPackage)
|
||||
}
|
||||
packages, err := definitiondb.FindPackages(requiredDef)
|
||||
if err != nil || len(packages) == 0 {
|
||||
required = requiredDef
|
||||
} else {
|
||||
|
@@ -129,6 +129,9 @@ var _ = Describe("Package", func() {
|
||||
Expect(a01.RequiresContains(definitions, a11)).To(BeTrue())
|
||||
Expect(a01.RequiresContains(definitions, a)).To(BeTrue())
|
||||
Expect(a.RequiresContains(definitions, a11)).ToNot(BeTrue())
|
||||
Expect(a.IsSelector()).To(BeTrue())
|
||||
Expect(a1.IsSelector()).To(BeFalse())
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
|
@@ -168,12 +168,16 @@ func (assertions PackagesAssertions) Order(definitiondb pkg.PackageDatabase, fin
|
||||
}
|
||||
|
||||
sort.Sort(unorderedAssertions)
|
||||
|
||||
// Build a topological graph
|
||||
//graph := toposort.NewGraph(len(unorderedAssertions))
|
||||
// graph.AddNodes(fingerprints...)
|
||||
for _, a := range unorderedAssertions {
|
||||
for _, requiredDef := range a.Package.GetRequires() {
|
||||
currentPkg := a.Package
|
||||
for _, requiredDef := range currentPkg.GetRequires() {
|
||||
if def, err := definitiondb.FindPackage(requiredDef); err == nil { // Provides: Get a chance of being override here
|
||||
requiredDef = def.(*pkg.DefaultPackage)
|
||||
}
|
||||
|
||||
// We cannot search for fingerprint, as we could have selector in versions.
|
||||
// We know that the assertions are unique for packages, so look for a package with such name in the assertions
|
||||
req := assertions.SearchByName(requiredDef.GetPackageName())
|
||||
@@ -182,7 +186,7 @@ func (assertions PackagesAssertions) Order(definitiondb pkg.PackageDatabase, fin
|
||||
}
|
||||
|
||||
// Expand also here, as we need to order them (or instead the solver should give back the dep correctly?)
|
||||
graph.AddEdge(a.Package.GetFingerPrint(), requiredDef.GetFingerPrint())
|
||||
graph.AddEdge(currentPkg.GetFingerPrint(), requiredDef.GetFingerPrint())
|
||||
}
|
||||
}
|
||||
result, err := graph.TopSort(fingerprint)
|
||||
|
@@ -393,6 +393,128 @@ var _ = Describe("Solver", func() {
|
||||
Expect(len(solution)).To(Equal(5))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("Support provides", func() {
|
||||
|
||||
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
|
||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
D2 := pkg.NewPackage("D", "1.9", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
D := pkg.NewPackage("D", "1.8", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
D1 := pkg.NewPackage("D", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
|
||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
|
||||
|
||||
D2.SetProvides([]*pkg.DefaultPackage{{Name: "E"}})
|
||||
A2 := pkg.NewPackage("A", "1.3", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "E", Version: ""}}, []*pkg.DefaultPackage{})
|
||||
|
||||
for _, p := range []pkg.Package{A, B, C, D, D1, D2, A2, E} {
|
||||
_, err := dbDefinitions.CreatePackage(p)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
}
|
||||
|
||||
for _, p := range []pkg.Package{} {
|
||||
_, err := dbInstalled.CreatePackage(p)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
}
|
||||
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||
|
||||
solution, err := s.Install([]pkg.Package{A2, B})
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: A2, Value: true}))
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: D1, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: D, Value: true}))
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: D2, Value: true}))
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: false}))
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: D1, Value: false}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: E, Value: true}))
|
||||
|
||||
Expect(len(solution)).To(Equal(5))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("Support provides with versions", func() {
|
||||
E := pkg.NewPackage("E", "1.3", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
|
||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
D2 := pkg.NewPackage("D", "1.9", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
D := pkg.NewPackage("D", "1.8", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
D1 := pkg.NewPackage("D", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
|
||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
|
||||
|
||||
D2.SetProvides([]*pkg.DefaultPackage{{Name: "E", Version: "1.3"}})
|
||||
A2 := pkg.NewPackage("A", "1.3", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "E", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
|
||||
|
||||
for _, p := range []pkg.Package{A, B, C, D, D1, D2, A2, E} {
|
||||
_, err := dbDefinitions.CreatePackage(p)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
}
|
||||
|
||||
for _, p := range []pkg.Package{} {
|
||||
_, err := dbInstalled.CreatePackage(p)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
}
|
||||
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||
|
||||
solution, err := s.Install([]pkg.Package{A2})
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: A2, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: D1, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: D, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: D2, Value: true}))
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: false}))
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: D1, Value: false}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: E, Value: true}))
|
||||
|
||||
Expect(len(solution)).To(Equal(4))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("Support provides with selectors", func() {
|
||||
E := pkg.NewPackage("E", "1.3", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
|
||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
D2 := pkg.NewPackage("D", "1.9", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
D := pkg.NewPackage("D", "1.8", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
D1 := pkg.NewPackage("D", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
|
||||
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
|
||||
|
||||
D2.SetProvides([]*pkg.DefaultPackage{{Name: "E", Version: ">=1.3"}})
|
||||
A2 := pkg.NewPackage("A", "1.3", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "E", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
|
||||
|
||||
for _, p := range []pkg.Package{A, B, C, D, D1, D2, A2, E} {
|
||||
_, err := dbDefinitions.CreatePackage(p)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
}
|
||||
|
||||
for _, p := range []pkg.Package{} {
|
||||
_, err := dbInstalled.CreatePackage(p)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
}
|
||||
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||
|
||||
solution, err := s.Install([]pkg.Package{A2})
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: A2, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: B, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: D1, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: D, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: C, Value: true}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: A, Value: true}))
|
||||
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: D2, Value: true}))
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: false}))
|
||||
Expect(solution).To(ContainElement(PackageAssert{Package: D1, Value: false}))
|
||||
Expect(solution).ToNot(ContainElement(PackageAssert{Package: E, Value: true}))
|
||||
|
||||
Expect(len(solution)).To(Equal(4))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("Uninstalls simple package correctly", func() {
|
||||
|
||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||
|
7
tests/fixtures/provides/c/build.yaml
vendored
Normal file
7
tests/fixtures/provides/c/build.yaml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
image: "alpine"
|
||||
prelude:
|
||||
- echo foo > /test
|
||||
- echo bar > /test2
|
||||
steps:
|
||||
- echo c > /c
|
||||
- echo c > /cd
|
7
tests/fixtures/provides/c/definition.yaml
vendored
Normal file
7
tests/fixtures/provides/c/definition.yaml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
category: "test"
|
||||
name: "c"
|
||||
version: "1.0"
|
||||
provides:
|
||||
- category: "bar"
|
||||
name: "foo"
|
||||
version: "1.0"
|
11
tests/fixtures/provides/d/build.yaml
vendored
Normal file
11
tests/fixtures/provides/d/build.yaml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
prelude:
|
||||
- echo foo > /test
|
||||
- echo bar > /test2
|
||||
steps:
|
||||
- echo s > /d
|
||||
- echo dd > /dd
|
||||
requires:
|
||||
- category: "bar"
|
||||
name: "foo"
|
||||
version: "1.0"
|
||||
|
3
tests/fixtures/provides/d/definition.yaml
vendored
Normal file
3
tests/fixtures/provides/d/definition.yaml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
category: "test"
|
||||
name: "d"
|
||||
version: "1.0"
|
0
tests/fixtures/provides/virtual/foo/build.yaml
vendored
Normal file
0
tests/fixtures/provides/virtual/foo/build.yaml
vendored
Normal file
3
tests/fixtures/provides/virtual/foo/definition.yaml
vendored
Normal file
3
tests/fixtures/provides/virtual/foo/definition.yaml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
name: "foo"
|
||||
version: "1.0"
|
||||
category: "bar"
|
7
tests/fixtures/provides_selector/c/build.yaml
vendored
Normal file
7
tests/fixtures/provides_selector/c/build.yaml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
image: "alpine"
|
||||
prelude:
|
||||
- echo foo > /test
|
||||
- echo bar > /test2
|
||||
steps:
|
||||
- echo c > /c
|
||||
- echo c > /cd
|
7
tests/fixtures/provides_selector/c/definition.yaml
vendored
Normal file
7
tests/fixtures/provides_selector/c/definition.yaml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
category: "test"
|
||||
name: "c"
|
||||
version: "1.0"
|
||||
provides:
|
||||
- category: "bar"
|
||||
name: "foo"
|
||||
version: ">=1.0"
|
11
tests/fixtures/provides_selector/d/build.yaml
vendored
Normal file
11
tests/fixtures/provides_selector/d/build.yaml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
prelude:
|
||||
- echo foo > /test
|
||||
- echo bar > /test2
|
||||
steps:
|
||||
- echo s > /d
|
||||
- echo dd > /dd
|
||||
requires:
|
||||
- category: "bar"
|
||||
name: "foo"
|
||||
version: ">=1.0"
|
||||
|
3
tests/fixtures/provides_selector/d/definition.yaml
vendored
Normal file
3
tests/fixtures/provides_selector/d/definition.yaml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
category: "test"
|
||||
name: "d"
|
||||
version: "1.0"
|
0
tests/fixtures/provides_selector/virtual/foo/build.yaml
vendored
Normal file
0
tests/fixtures/provides_selector/virtual/foo/build.yaml
vendored
Normal file
3
tests/fixtures/provides_selector/virtual/foo/definition.yaml
vendored
Normal file
3
tests/fixtures/provides_selector/virtual/foo/definition.yaml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
name: "foo"
|
||||
version: "1.1"
|
||||
category: "bar"
|
Reference in New Issue
Block a user