Introduce install --relaxed

It introduces a relaxed way to install packages with loose deps. Default
installation now will by default prefer up-to-date packages during
selection.

Also:
- Upgrade now it's used in install so it have to return the full system view also when there is nothing to upgrade
- Avoid checking upgrade upfront if relaxed is on
This commit is contained in:
Ettore Di Giacinto
2021-10-09 17:36:13 +02:00
parent 77b4c9a972
commit e64f68d36b
7 changed files with 329 additions and 64 deletions

View File

@@ -16,6 +16,8 @@
package solver_test
import (
"fmt"
pkg "github.com/mudler/luet/pkg/package"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -36,6 +38,143 @@ var _ = Describe("Solver", func() {
dbDefinitions = pkg.NewInMemoryDatabase(false)
s = NewSolver(Options{Type: SingleCoreSimple}, dbInstalled, dbDefinitions, db)
})
Context("Select of best available package", func() {
It("picks the best versions available for each package, excluding the ones manually specified while installing", func() {
B1 := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
B2 := pkg.NewPackage("B", "1.2", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
B3 := pkg.NewPackage("B", "1.3", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
B4 := pkg.NewPackage("B", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
A1 := pkg.NewPackage("A", "1.1", []*pkg.DefaultPackage{
pkg.NewPackage("B", ">=0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}),
}, []*pkg.DefaultPackage{})
A2 := pkg.NewPackage("A", "1.2", []*pkg.DefaultPackage{
pkg.NewPackage("B", ">=0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}),
}, []*pkg.DefaultPackage{})
D := pkg.NewPackage("D", "1.0", []*pkg.DefaultPackage{
pkg.NewPackage("A", ">=0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}),
}, []*pkg.DefaultPackage{})
C := pkg.NewPackage("C", "1", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
for _, p := range []pkg.Package{A1, A2, B1, B2, B3, B4, C, D} {
_, err := dbDefinitions.CreatePackage(p)
Expect(err).ToNot(HaveOccurred())
}
for _, p := range []pkg.Package{C} {
_, err := dbInstalled.CreatePackage(p)
Expect(err).ToNot(HaveOccurred())
}
s = NewSolver(Options{Type: SingleCoreSimple}, dbInstalled, dbDefinitions, db)
solution, err := s.(*Solver).Install([]pkg.Package{D})
fmt.Println(solution)
Expect(err).ToNot(HaveOccurred())
Expect(len(solution)).To(Equal(8))
// Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: A2, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: B4, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: A1, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B1, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B2, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B3, Value: false}))
s = NewSolver(Options{Type: SingleCoreSimple}, dbInstalled, dbDefinitions, db)
solution, err = s.(*Solver).Install([]pkg.Package{D, B2})
fmt.Println(solution)
Expect(err).ToNot(HaveOccurred())
Expect(len(solution)).To(Equal(8))
// Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: A2, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: B2, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: A1, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B1, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B4, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B3, Value: false}))
})
It("picks the best available excluding those manually input. In this case we the input is a selector >=0", func() {
B1 := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
B2 := pkg.NewPackage("B", "1.2", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
B3 := pkg.NewPackage("B", "1.3", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
B4 := pkg.NewPackage("B", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
A1 := pkg.NewPackage("A", "1.1", []*pkg.DefaultPackage{
pkg.NewPackage("B", ">=0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}),
}, []*pkg.DefaultPackage{})
A2 := pkg.NewPackage("A", "1.2", []*pkg.DefaultPackage{
pkg.NewPackage("B", ">=0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}),
}, []*pkg.DefaultPackage{})
D := pkg.NewPackage("D", "1.0", []*pkg.DefaultPackage{
pkg.NewPackage("A", ">=0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}),
}, []*pkg.DefaultPackage{})
C := pkg.NewPackage("C", "1", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
for _, p := range []pkg.Package{A1, A2, B1, B2, B3, B4, C, D} {
_, err := dbDefinitions.CreatePackage(p)
Expect(err).ToNot(HaveOccurred())
}
for _, p := range []pkg.Package{C} {
_, err := dbInstalled.CreatePackage(p)
Expect(err).ToNot(HaveOccurred())
}
s = NewSolver(Options{Type: SingleCoreSimple}, dbInstalled, dbDefinitions, db)
solution, err := s.(*Solver).Install([]pkg.Package{pkg.NewPackage("D", ">=0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})})
fmt.Println(solution)
Expect(err).ToNot(HaveOccurred())
Expect(len(solution)).To(Equal(8))
// Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: A2, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: B4, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: A1, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B1, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B2, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B3, Value: false}))
s = NewSolver(Options{Type: SingleCoreSimple}, dbInstalled, dbDefinitions, db)
solution, err = s.(*Solver).Install([]pkg.Package{pkg.NewPackage("D", ">=0", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}), B2})
fmt.Println(solution)
Expect(err).ToNot(HaveOccurred())
Expect(len(solution)).To(Equal(8))
// Expect(solution).To(ContainElement(PackageAssert{Package: B, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: C, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: D, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: A2, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: B2, Value: true}))
Expect(solution).To(ContainElement(PackageAssert{Package: A1, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B1, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B4, Value: false}))
Expect(solution).To(ContainElement(PackageAssert{Package: B3, Value: false}))
})
})
Context("Simple set", func() {
It("Solves correctly if the selected package has no requirements or conflicts and we have nothing installed yet", func() {