Create a type for lists of PackageAssertion, and move Order() inside it

This commit is contained in:
Ettore Di Giacinto
2019-11-11 11:02:32 +01:00
parent ebd4cfc318
commit 2dd56e9e49
4 changed files with 183 additions and 154 deletions

View File

@@ -20,17 +20,15 @@ import (
"github.com/crillab/gophersat/bf"
pkg "github.com/mudler/luet/pkg/package"
toposort "github.com/philopon/go-toposort"
)
// PackageSolver is an interface to a generic package solving algorithm
type PackageSolver interface {
SetWorld(p []pkg.Package)
Install(p []pkg.Package) ([]PackageAssert, error)
Install(p []pkg.Package) (PackagesAssertions, error)
Uninstall(candidate pkg.Package) ([]pkg.Package, error)
ConflictsWithInstalled(p pkg.Package) (bool, error)
ConflictsWith(p pkg.Package, ls []pkg.Package) (bool, error)
Order([]PackageAssert) []PackageAssert
}
// Solver is the default solver for luet
@@ -253,7 +251,7 @@ func (s *Solver) solve(f bf.Formula) (map[string]bool, bf.Formula, error) {
}
// Solve builds the formula given the current state and returns package assertions
func (s *Solver) Solve() ([]PackageAssert, error) {
func (s *Solver) Solve() (PackagesAssertions, error) {
f, err := s.BuildFormula()
@@ -269,58 +267,16 @@ func (s *Solver) Solve() ([]PackageAssert, error) {
return DecodeModel(model)
}
func (s *Solver) Order(assertions []PackageAssert) []PackageAssert {
orderedAssertions := []PackageAssert{}
unorderedAssertions := []PackageAssert{}
fingerprints := []string{}
tmpMap := map[string]PackageAssert{}
for _, a := range assertions {
if a.Package.Flagged() {
unorderedAssertions = append(unorderedAssertions, a) // Build a list of the ones that must be ordered
fingerprints = append(fingerprints, a.Package.GetFingerPrint())
tmpMap[a.Package.GetFingerPrint()] = a
} else {
orderedAssertions = append(orderedAssertions, a) // Keep last the ones which are not meant to be installed
}
}
// Build a topological graph
graph := toposort.NewGraph(len(unorderedAssertions))
graph.AddNodes(fingerprints...)
for _, a := range unorderedAssertions {
for _, req := range a.Package.GetRequires() {
graph.AddEdge(a.Package.GetFingerPrint(), req.GetFingerPrint())
}
}
result, ok := graph.Toposort()
if !ok {
panic("cycle detected")
}
for _, res := range result {
a, ok := tmpMap[res]
if !ok {
panic("Sort order - this shouldn't happen")
}
orderedAssertions = append([]PackageAssert{a}, orderedAssertions...) // push upfront
}
return orderedAssertions
}
// Install given a list of packages, returns package assertions to indicate the packages that must be installed in the system in order
// to statisfy all the constraints
func (s *Solver) Install(coll []pkg.Package) ([]PackageAssert, error) {
func (s *Solver) Install(coll []pkg.Package) (PackagesAssertions, error) {
for _, v := range coll {
v.IsFlagged(false)
}
s.Wanted = coll
if s.noRulesWorld() {
var ass []PackageAssert
var ass PackagesAssertions
for _, p := range s.Installed {
ass = append(ass, PackageAssert{Package: p.IsFlagged(true), Value: true})