diff --git a/pkg/installer/installer.go b/pkg/installer/installer.go index b158cf6b..6f994ac0 100644 --- a/pkg/installer/installer.go +++ b/pkg/installer/installer.go @@ -112,58 +112,15 @@ func (l *LuetInstaller) Install(p []pkg.Package, s *System) error { // First match packages against repositories by priority // matches := syncedRepos.PackageMatches(p) - // Get installed definition - installed, err := s.World() - if err != nil { - return errors.Wrap(err, "Failed generating installed world") - } - // compute a "big" world - allrepoWorld := syncedRepos.World() + allRepos := pkg.NewInMemoryDatabase(false) + syncedRepos.SyncDatabase(allRepos) - // If installed exists in the world, we need to use them to make the solver point to them - realInstalled := []pkg.Package{} - for _, i := range installed { - var found pkg.Package - I: - for _, p := range allrepoWorld { - if p.Matches(i) { - found = p - break I - } - } - - if found != nil { - realInstalled = append(realInstalled, found) - - } else { - realInstalled = append(realInstalled, i) - } + solv := solver.NewSolver(s.Database, allRepos, pkg.NewInMemoryDatabase(false)) + solution, err := solv.Install(p) + if err != nil { + return errors.Wrap(err, "Failed solving solution for package") } - - allwanted := []pkg.Package{} - for _, wanted := range p { - var found pkg.Package - - W: - for _, p := range allrepoWorld { - if p.Matches(wanted) { - found = p - break W - } - } - - if found != nil { - allwanted = append(allwanted, found) - - } else { - return errors.New("Package requested to install not found") - } - } - - solv := solver.NewSolver(realInstalled, allrepoWorld, pkg.NewInMemoryDatabase(false)) - solution, err := solv.Install(allwanted) - // Gathers things to install toInstall := map[string]ArtifactMatch{} for _, assertion := range solution { @@ -205,9 +162,9 @@ func (l *LuetInstaller) Install(p []pkg.Package, s *System) error { executedFinalizer := map[string]bool{} // TODO: Lower those errors as warning - for _, w := range allwanted { + for _, w := range p { // Finalizers needs to run in order and in sequence. - ordered := solution.Order(w.GetFingerPrint()) + ordered := solution.Order(allRepos, w.GetFingerPrint()) for _, ass := range ordered { if ass.Value { // Annotate to the system that the package was installed @@ -228,7 +185,7 @@ func (l *LuetInstaller) Install(p []pkg.Package, s *System) error { return errors.New("Couldn't find ArtifactMatch for " + ass.Package.GetFingerPrint()) } - treePackage, err := installed.Repository.GetTree().Tree().FindPackage(ass.Package) + treePackage, err := installed.Repository.GetTree().GetDatabase().FindPackage(ass.Package) if err != nil { return errors.Wrap(err, "Error getting package "+ass.Package.GetFingerPrint()) } @@ -351,17 +308,11 @@ func (l *LuetInstaller) Uninstall(p pkg.Package, s *System) error { // compute uninstall from all world - remove packages in parallel - run uninstall finalizer (in order) - mark the uninstallation in db // Get installed definition - selected, err := s.Database.FindPackage(p) + solv := solver.NewSolver(s.Database, s.Database, pkg.NewInMemoryDatabase(false)) + solution, err := solv.Uninstall(p) if err != nil { - return errors.Wrap(err, "Package not installed") + return errors.Wrap(err, "Uninstall failed") } - installed, err := s.World() - if err != nil { - return errors.Wrap(err, "Failed generating installed world") - } - - solv := solver.NewSolver(installed, installed, pkg.NewInMemoryDatabase(false)) - solution, err := solv.Uninstall(selected) for _, p := range solution { Info("Uninstalling", p.GetFingerPrint()) err := l.uninstall(p, s) diff --git a/pkg/installer/installer_test.go b/pkg/installer/installer_test.go index 849724af..a33d766f 100644 --- a/pkg/installer/installer_test.go +++ b/pkg/installer/installer_test.go @@ -44,13 +44,10 @@ var _ = Describe("Installer", func() { err = generalRecipe.Load("../../tests/fixtures/buildable") Expect(err).ToNot(HaveOccurred()) - Expect(generalRecipe.Tree()).ToNot(BeNil()) // It should be populated back at this point - Expect(len(generalRecipe.Tree().GetPackageSet().GetPackages())).To(Equal(3)) + Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.Tree(), generalRecipe.Tree().GetPackageSet()) - err = compiler.Prepare(1) - Expect(err).ToNot(HaveOccurred()) + compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -157,13 +154,10 @@ uri: "`+tmpdir+`" err = generalRecipe.Load("../../tests/fixtures/buildable") Expect(err).ToNot(HaveOccurred()) - Expect(generalRecipe.Tree()).ToNot(BeNil()) // It should be populated back at this point - Expect(len(generalRecipe.Tree().GetPackageSet().GetPackages())).To(Equal(3)) + Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.Tree(), generalRecipe.Tree().GetPackageSet()) - err = compiler.Prepare(1) - Expect(err).ToNot(HaveOccurred()) + compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) diff --git a/pkg/installer/repository.go b/pkg/installer/repository.go index 1ded7fd6..239d1d3f 100644 --- a/pkg/installer/repository.go +++ b/pkg/installer/repository.go @@ -24,7 +24,6 @@ import ( "strings" "github.com/mudler/luet/pkg/installer/client" - . "github.com/mudler/luet/pkg/logger" "github.com/ghodss/yaml" "github.com/mudler/luet/pkg/compiler" @@ -269,12 +268,7 @@ func (r Repositories) World() []pkg.Package { // Get Uniques. Walk in reverse so the definitions of most prio-repo overwrites lower ones // In this way, when we will walk again later the deps sorting them by most higher prio we have better chance of success. for i := len(r) - 1; i >= 0; i-- { - w, err := r[i].GetTree().Tree().World() - if err != nil { - Warning("Failed computing world for " + r[i].GetName()) - continue - } - for _, p := range w { + for _, p := range r[i].GetTree().GetDatabase().World() { cache[p.GetFingerPrint()] = p } } @@ -286,6 +280,22 @@ func (r Repositories) World() []pkg.Package { return world } +func (r Repositories) SyncDatabase(d pkg.PackageDatabase) { + cache := map[string]bool{} + + // Get Uniques. Walk in reverse so the definitions of most prio-repo overwrites lower ones + // In this way, when we will walk again later the deps sorting them by most higher prio we have better chance of success. + for i := len(r) - 1; i >= 0; i-- { + for _, p := range r[i].GetTree().GetDatabase().World() { + if _, ok := cache[p.GetFingerPrint()]; !ok { + cache[p.GetFingerPrint()] = true + d.CreatePackage(p) + } + } + } + +} + type PackageMatch struct { Repo Repository Package pkg.Package @@ -300,7 +310,7 @@ func (re Repositories) PackageMatches(p []pkg.Package) []PackageMatch { PACKAGE: for _, pack := range p { for _, r := range re { - c, err := r.GetTree().Tree().GetPackageSet().FindPackage(pack) + c, err := r.GetTree().GetDatabase().FindPackage(pack) if err == nil { matches = append(matches, PackageMatch{Package: c, Repo: r}) continue PACKAGE @@ -318,10 +328,8 @@ func (re Repositories) Search(s string) []PackageMatch { var matches []PackageMatch for _, r := range re { - ps := r.GetTree().Tree().GetPackageSet() - for _, k := range ps.GetPackages() { - pack, err := ps.GetPackage(k) - if err == nil && term.MatchString(pack.GetName()) { + for _, pack := range r.GetTree().GetDatabase().World() { + if term.MatchString(pack.GetName()) { matches = append(matches, PackageMatch{Package: pack, Repo: r}) } } diff --git a/pkg/installer/repository_test.go b/pkg/installer/repository_test.go index b06c68fa..52e65f7c 100644 --- a/pkg/installer/repository_test.go +++ b/pkg/installer/repository_test.go @@ -43,13 +43,10 @@ var _ = Describe("Repository", func() { err = generalRecipe.Load("../../tests/fixtures/buildable") Expect(err).ToNot(HaveOccurred()) - Expect(generalRecipe.Tree()).ToNot(BeNil()) // It should be populated back at this point - Expect(len(generalRecipe.Tree().GetPackageSet().GetPackages())).To(Equal(3)) + Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.Tree(), generalRecipe.Tree().GetPackageSet()) - err = compiler.Prepare(1) - Expect(err).ToNot(HaveOccurred()) + compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -101,10 +98,10 @@ var _ = Describe("Repository", func() { builder1 := tree.NewInstallerRecipe(pkg.NewInMemoryDatabase(false)) builder2 := tree.NewInstallerRecipe(pkg.NewInMemoryDatabase(false)) - _, err := builder1.Tree().GetPackageSet().CreatePackage(package1) + _, err := builder1.GetDatabase().CreatePackage(package1) Expect(err).ToNot(HaveOccurred()) - _, err = builder2.Tree().GetPackageSet().CreatePackage(package2) + _, err = builder2.GetDatabase().CreatePackage(package2) Expect(err).ToNot(HaveOccurred()) repo1 := &LuetRepository{Name: "test1", Tree: builder1} repo2 := &LuetRepository{Name: "test2", Tree: builder2} diff --git a/pkg/installer/system.go b/pkg/installer/system.go index 6316c9c6..fc35ef67 100644 --- a/pkg/installer/system.go +++ b/pkg/installer/system.go @@ -2,7 +2,6 @@ package installer import ( pkg "github.com/mudler/luet/pkg/package" - "github.com/mudler/luet/pkg/tree" ) type System struct { @@ -11,7 +10,5 @@ type System struct { } func (s *System) World() ([]pkg.Package, error) { - t := tree.NewDefaultTree() - t.SetPackageSet(s.Database) - return t.World() + return s.Database.World(), nil }