mirror of
https://github.com/mudler/luet.git
synced 2025-09-05 17:20:29 +00:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2c2e6065d9 | ||
|
46014fb9c1 | ||
|
ada9d886fa | ||
|
584b980644 | ||
|
a1d8ef1422 | ||
|
7b6e4a2176 | ||
|
3befbfa915 | ||
|
8dd756ec96 |
@@ -38,7 +38,7 @@ var Verbose bool
|
|||||||
var LockedCommands = []string{"install", "uninstall", "upgrade"}
|
var LockedCommands = []string{"install", "uninstall", "upgrade"}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LuetCLIVersion = "0.7.6"
|
LuetCLIVersion = "0.7.7"
|
||||||
LuetEnvPrefix = "LUET"
|
LuetEnvPrefix = "LUET"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -57,6 +57,8 @@ var uninstallCmd = &cobra.Command{
|
|||||||
attempts := LuetCfg.Viper.GetInt("solver.max_attempts")
|
attempts := LuetCfg.Viper.GetInt("solver.max_attempts")
|
||||||
force := LuetCfg.Viper.GetBool("force")
|
force := LuetCfg.Viper.GetBool("force")
|
||||||
nodeps := LuetCfg.Viper.GetBool("nodeps")
|
nodeps := LuetCfg.Viper.GetBool("nodeps")
|
||||||
|
full, _ := cmd.Flags().GetBool("full")
|
||||||
|
checkconflicts, _ := cmd.Flags().GetBool("conflictscheck")
|
||||||
|
|
||||||
LuetCfg.GetSolverOptions().Type = stype
|
LuetCfg.GetSolverOptions().Type = stype
|
||||||
LuetCfg.GetSolverOptions().LearnRate = float32(rate)
|
LuetCfg.GetSolverOptions().LearnRate = float32(rate)
|
||||||
@@ -66,10 +68,12 @@ var uninstallCmd = &cobra.Command{
|
|||||||
Debug("Solver", LuetCfg.GetSolverOptions().CompactString())
|
Debug("Solver", LuetCfg.GetSolverOptions().CompactString())
|
||||||
|
|
||||||
inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{
|
inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{
|
||||||
Concurrency: LuetCfg.GetGeneral().Concurrency,
|
Concurrency: LuetCfg.GetGeneral().Concurrency,
|
||||||
SolverOptions: *LuetCfg.GetSolverOptions(),
|
SolverOptions: *LuetCfg.GetSolverOptions(),
|
||||||
NoDeps: nodeps,
|
NoDeps: nodeps,
|
||||||
Force: force,
|
Force: force,
|
||||||
|
FullUninstall: full,
|
||||||
|
CheckConflicts: checkconflicts,
|
||||||
})
|
})
|
||||||
|
|
||||||
if LuetCfg.GetSystem().DatabaseEngine == "boltdb" {
|
if LuetCfg.GetSystem().DatabaseEngine == "boltdb" {
|
||||||
@@ -98,8 +102,10 @@ func init() {
|
|||||||
uninstallCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate")
|
uninstallCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate")
|
||||||
uninstallCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")
|
uninstallCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")
|
||||||
uninstallCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts")
|
uninstallCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts")
|
||||||
uninstallCmd.Flags().Bool("nodeps", false, "Don't consider package dependencies (harmful!)")
|
uninstallCmd.Flags().Bool("nodeps", false, "Don't consider package dependencies (harmful! overrides checkconflicts and full!)")
|
||||||
uninstallCmd.Flags().Bool("force", false, "Force uninstall")
|
uninstallCmd.Flags().Bool("force", false, "Force uninstall")
|
||||||
|
uninstallCmd.Flags().Bool("full", false, "Attempts to remove as much packages as possible which aren't required (slow)")
|
||||||
|
uninstallCmd.Flags().Bool("conflictscheck", true, "Check if the package marked for deletion is required by other packages")
|
||||||
|
|
||||||
RootCmd.AddCommand(uninstallCmd)
|
RootCmd.AddCommand(uninstallCmd)
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,8 @@ type LuetInstallerOptions struct {
|
|||||||
OnlyDeps bool
|
OnlyDeps bool
|
||||||
Force bool
|
Force bool
|
||||||
PreserveSystemEssentialData bool
|
PreserveSystemEssentialData bool
|
||||||
|
FullUninstall bool
|
||||||
|
CheckConflicts bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type LuetInstaller struct {
|
type LuetInstaller struct {
|
||||||
@@ -132,14 +134,12 @@ func (l *LuetInstaller) swap(syncedRepos Repositories, toRemove pkg.Packages, to
|
|||||||
// if the old A results installed in the system. This is due to the fact that
|
// if the old A results installed in the system. This is due to the fact that
|
||||||
// now the solver enforces the constraints and explictly denies two packages
|
// now the solver enforces the constraints and explictly denies two packages
|
||||||
// of the same version installed.
|
// of the same version installed.
|
||||||
forced := false
|
forced := l.Options.Force
|
||||||
if l.Options.Force {
|
|
||||||
forced = true
|
|
||||||
}
|
|
||||||
l.Options.Force = true
|
l.Options.Force = true
|
||||||
|
|
||||||
for _, u := range toRemove {
|
for _, u := range toRemove {
|
||||||
Info(":package: Marked for deletion", u.HumanReadableString())
|
Info(":package:", u.HumanReadableString(), "Marked for deletion")
|
||||||
|
|
||||||
err := l.Uninstall(u, s)
|
err := l.Uninstall(u, s)
|
||||||
if err != nil && !l.Options.Force {
|
if err != nil && !l.Options.Force {
|
||||||
@@ -309,7 +309,7 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp pkg.Packages, s *Sy
|
|||||||
packagesToInstall = append(packagesToInstall, currentPack)
|
packagesToInstall = append(packagesToInstall, currentPack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Info(":deciduous_tree: Finding packages to install")
|
||||||
// Gathers things to install
|
// Gathers things to install
|
||||||
for _, currentPack := range packagesToInstall {
|
for _, currentPack := range packagesToInstall {
|
||||||
// Check if package is already installed.
|
// Check if package is already installed.
|
||||||
@@ -331,6 +331,7 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp pkg.Packages, s *Sy
|
|||||||
// Filter out already installed
|
// Filter out already installed
|
||||||
if _, err := s.Database.FindPackage(currentPack); err != nil {
|
if _, err := s.Database.FindPackage(currentPack); err != nil {
|
||||||
toInstall[currentPack.GetFingerPrint()] = ArtifactMatch{Package: currentPack, Artifact: artefact, Repository: matches[0].Repo}
|
toInstall[currentPack.GetFingerPrint()] = ArtifactMatch{Package: currentPack, Artifact: artefact, Repository: matches[0].Repo}
|
||||||
|
Info("\t:package:", currentPack.HumanReadableString(), "from repository", matches[0].Repo.GetName())
|
||||||
}
|
}
|
||||||
break A
|
break A
|
||||||
}
|
}
|
||||||
@@ -569,17 +570,35 @@ func (l *LuetInstaller) uninstall(p pkg.Package, s *System) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *LuetInstaller) Uninstall(p pkg.Package, s *System) error {
|
func (l *LuetInstaller) Uninstall(p pkg.Package, s *System) error {
|
||||||
|
Spinner(32)
|
||||||
|
defer SpinnerStop()
|
||||||
|
|
||||||
|
Info("Uninstalling :package:", p.HumanReadableString(), "hang tight")
|
||||||
|
|
||||||
// compute uninstall from all world - remove packages in parallel - run uninstall finalizer (in order) TODO - mark the uninstallation in db
|
// compute uninstall from all world - remove packages in parallel - run uninstall finalizer (in order) TODO - mark the uninstallation in db
|
||||||
// Get installed definition
|
// Get installed definition
|
||||||
|
checkConflicts := l.Options.CheckConflicts
|
||||||
checkConflicts := true
|
full := l.Options.FullUninstall
|
||||||
if l.Options.Force == true {
|
if l.Options.Force == true { // IF forced, we want to remove the package and all its requires
|
||||||
checkConflicts = false
|
checkConflicts = false
|
||||||
|
full = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a temporary DB with the installed packages
|
||||||
|
// so the solver is much faster finding the deptree
|
||||||
|
installedtmp := pkg.NewInMemoryDatabase(false)
|
||||||
|
|
||||||
|
for _, i := range s.Database.World() {
|
||||||
|
_, err := installedtmp.CreatePackage(i)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Failed create temporary in-memory db")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !l.Options.NoDeps {
|
if !l.Options.NoDeps {
|
||||||
solv := solver.NewResolver(s.Database, s.Database, pkg.NewInMemoryDatabase(false), l.Options.SolverOptions.Resolver())
|
Info("Finding :package:", p.HumanReadableString(), "dependency graph :deciduous_tree:")
|
||||||
solution, err := solv.Uninstall(p, checkConflicts)
|
solv := solver.NewResolver(installedtmp, installedtmp, pkg.NewInMemoryDatabase(false), l.Options.SolverOptions.Resolver())
|
||||||
|
solution, err := solv.Uninstall(p, checkConflicts, full)
|
||||||
if err != nil && !l.Options.Force {
|
if err != nil && !l.Options.Force {
|
||||||
return errors.Wrap(err, "Could not solve the uninstall constraints. Tip: try with --solver-type qlearning or with --force, or by removing packages excluding their dependencies with --nodeps")
|
return errors.Wrap(err, "Could not solve the uninstall constraints. Tip: try with --solver-type qlearning or with --force, or by removing packages excluding their dependencies with --nodeps")
|
||||||
}
|
}
|
||||||
@@ -596,7 +615,7 @@ func (l *LuetInstaller) Uninstall(p pkg.Package, s *System) error {
|
|||||||
if err != nil && !l.Options.Force {
|
if err != nil && !l.Options.Force {
|
||||||
return errors.Wrap(err, "Uninstall failed")
|
return errors.Wrap(err, "Uninstall failed")
|
||||||
}
|
}
|
||||||
Info(":package: ", p.HumanReadableString(), "uninstalled")
|
Info(":package:", p.HumanReadableString(), "uninstalled")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
|
@@ -18,6 +18,8 @@ package solver
|
|||||||
import (
|
import (
|
||||||
|
|
||||||
//. "github.com/mudler/luet/pkg/logger"
|
//. "github.com/mudler/luet/pkg/logger"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/crillab/gophersat/bf"
|
"github.com/crillab/gophersat/bf"
|
||||||
@@ -28,9 +30,11 @@ import (
|
|||||||
type PackageSolver interface {
|
type PackageSolver interface {
|
||||||
SetDefinitionDatabase(pkg.PackageDatabase)
|
SetDefinitionDatabase(pkg.PackageDatabase)
|
||||||
Install(p pkg.Packages) (PackagesAssertions, error)
|
Install(p pkg.Packages) (PackagesAssertions, error)
|
||||||
Uninstall(candidate pkg.Package, checkconflicts bool) (pkg.Packages, error)
|
Uninstall(candidate pkg.Package, checkconflicts, full bool) (pkg.Packages, error)
|
||||||
ConflictsWithInstalled(p pkg.Package) (bool, error)
|
ConflictsWithInstalled(p pkg.Package) (bool, error)
|
||||||
ConflictsWith(p pkg.Package, ls pkg.Packages) (bool, error)
|
ConflictsWith(p pkg.Package, ls pkg.Packages) (bool, error)
|
||||||
|
Conflicts(pack pkg.Package, lsp pkg.Packages) (bool, error)
|
||||||
|
|
||||||
World() pkg.Packages
|
World() pkg.Packages
|
||||||
Upgrade(checkconflicts bool) (pkg.Packages, PackagesAssertions, error)
|
Upgrade(checkconflicts bool) (pkg.Packages, PackagesAssertions, error)
|
||||||
|
|
||||||
@@ -149,6 +153,43 @@ func (s *Solver) getList(db pkg.PackageDatabase, lsp pkg.Packages) (pkg.Packages
|
|||||||
return ls, nil
|
return ls, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Conflicts acts like ConflictsWith, but uses package's reverse dependencies to
|
||||||
|
// determine if it conflicts with the given set
|
||||||
|
func (s *Solver) Conflicts(pack pkg.Package, lsp pkg.Packages) (bool, error) {
|
||||||
|
p, err := s.DefinitionDatabase.FindPackage(pack)
|
||||||
|
if err != nil {
|
||||||
|
p = pack
|
||||||
|
}
|
||||||
|
|
||||||
|
ls, err := s.getList(s.DefinitionDatabase, lsp)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrap(err, "Package not found in definition db")
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.noRulesWorld() {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
temporarySet := pkg.NewInMemoryDatabase(false)
|
||||||
|
for _, p := range ls {
|
||||||
|
temporarySet.CreatePackage(p)
|
||||||
|
}
|
||||||
|
visited := make(map[string]interface{})
|
||||||
|
revdeps := p.ExpandedRevdeps(temporarySet, visited)
|
||||||
|
|
||||||
|
var revdepsErr error
|
||||||
|
for _, r := range revdeps {
|
||||||
|
if revdepsErr == nil {
|
||||||
|
revdepsErr = errors.New("")
|
||||||
|
}
|
||||||
|
revdepsErr = errors.New(fmt.Sprintf("%s\n%s", revdepsErr.Error(), r.HumanReadableString()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return len(revdeps) != 0, revdepsErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConflictsWith return true if a package is part of the requirement set of a list of package
|
||||||
|
// return false otherwise (and thus it is NOT relevant to the given list)
|
||||||
func (s *Solver) ConflictsWith(pack pkg.Package, lsp pkg.Packages) (bool, error) {
|
func (s *Solver) ConflictsWith(pack pkg.Package, lsp pkg.Packages) (bool, error) {
|
||||||
p, err := s.DefinitionDatabase.FindPackage(pack)
|
p, err := s.DefinitionDatabase.FindPackage(pack)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -240,7 +281,7 @@ func (s *Solver) Upgrade(checkconflicts bool) (pkg.Packages, PackagesAssertions,
|
|||||||
s2.SetResolver(s.Resolver)
|
s2.SetResolver(s.Resolver)
|
||||||
// Then try to uninstall the versions in the system, and store that tree
|
// Then try to uninstall the versions in the system, and store that tree
|
||||||
for _, p := range toUninstall {
|
for _, p := range toUninstall {
|
||||||
r, err := s.Uninstall(p, checkconflicts)
|
r, err := s.Uninstall(p, checkconflicts, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "Could not compute upgrade - couldn't uninstall selected candidate "+p.GetFingerPrint())
|
return nil, nil, errors.Wrap(err, "Could not compute upgrade - couldn't uninstall selected candidate "+p.GetFingerPrint())
|
||||||
}
|
}
|
||||||
@@ -261,7 +302,7 @@ func (s *Solver) Upgrade(checkconflicts bool) (pkg.Packages, PackagesAssertions,
|
|||||||
|
|
||||||
// Uninstall takes a candidate package and return a list of packages that would be removed
|
// Uninstall takes a candidate package and return a list of packages that would be removed
|
||||||
// in order to purge the candidate. Returns error if unsat.
|
// in order to purge the candidate. Returns error if unsat.
|
||||||
func (s *Solver) Uninstall(c pkg.Package, checkconflicts bool) (pkg.Packages, error) {
|
func (s *Solver) Uninstall(c pkg.Package, checkconflicts, full bool) (pkg.Packages, error) {
|
||||||
var res pkg.Packages
|
var res pkg.Packages
|
||||||
candidate, err := s.InstalledDatabase.FindPackage(c)
|
candidate, err := s.InstalledDatabase.FindPackage(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -280,6 +321,16 @@ func (s *Solver) Uninstall(c pkg.Package, checkconflicts bool) (pkg.Packages, er
|
|||||||
// Build a fake "Installed" - Candidate and its requires tree
|
// Build a fake "Installed" - Candidate and its requires tree
|
||||||
var InstalledMinusCandidate pkg.Packages
|
var InstalledMinusCandidate pkg.Packages
|
||||||
|
|
||||||
|
// We are asked to not perform a full uninstall (checking all the possible requires that could
|
||||||
|
// be removed). Let's only check if we can remove the selected package
|
||||||
|
if !full && checkconflicts {
|
||||||
|
if conflicts, err := s.Conflicts(candidate, s.Installed()); conflicts {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return pkg.Packages{candidate}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Can be optimized
|
// TODO: Can be optimized
|
||||||
for _, i := range s.Installed() {
|
for _, i := range s.Installed() {
|
||||||
if !i.Matches(candidate) {
|
if !i.Matches(candidate) {
|
||||||
|
@@ -547,7 +547,7 @@ var _ = Describe("Solver", func() {
|
|||||||
}
|
}
|
||||||
s = NewSolver(dbInstalled, dbDefinitions, db)
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
solution, err := s.Uninstall(A, true)
|
solution, err := s.Uninstall(A, true, true)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
||||||
@@ -573,7 +573,7 @@ var _ = Describe("Solver", func() {
|
|||||||
}
|
}
|
||||||
s = NewSolver(dbInstalled, dbDefinitions, db)
|
s = NewSolver(dbInstalled, dbDefinitions, db)
|
||||||
|
|
||||||
solution, err := s.Uninstall(&pkg.DefaultPackage{Name: "A", Version: ">1.0"}, true)
|
solution, err := s.Uninstall(&pkg.DefaultPackage{Name: "A", Version: ">1.0"}, true, true)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
||||||
@@ -672,6 +672,99 @@ var _ = Describe("Solver", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(val).ToNot(BeTrue())
|
Expect(val).ToNot(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("Find conflicts using revdeps", func() {
|
||||||
|
|
||||||
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := s.Conflicts(A, dbInstalled.World())
|
||||||
|
Expect(err.Error()).To(Equal("\n/B-"))
|
||||||
|
Expect(val).To(BeTrue())
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Find nested conflicts with revdeps", func() {
|
||||||
|
|
||||||
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := s.Conflicts(D, dbInstalled.World())
|
||||||
|
Expect(err.Error()).To(Equal("\n/A-\n/B-"))
|
||||||
|
Expect(val).To(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Doesn't find nested conflicts with revdeps", func() {
|
||||||
|
|
||||||
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{A}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := s.Conflicts(C, dbInstalled.World())
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(val).ToNot(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Doesn't find conflicts with revdeps", func() {
|
||||||
|
|
||||||
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
B := pkg.NewPackage("B", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbDefinitions.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range []pkg.Package{A, B, C, D} {
|
||||||
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
}
|
||||||
|
val, err := s.Conflicts(C, dbInstalled.World())
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(val).ToNot(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
It("Uninstalls simple packages not in world correctly", func() {
|
It("Uninstalls simple packages not in world correctly", func() {
|
||||||
|
|
||||||
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
|
||||||
@@ -688,7 +781,7 @@ var _ = Describe("Solver", func() {
|
|||||||
_, err := dbInstalled.CreatePackage(p)
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
solution, err := s.Uninstall(A, true)
|
solution, err := s.Uninstall(A, true, true)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
||||||
@@ -712,7 +805,7 @@ var _ = Describe("Solver", func() {
|
|||||||
_, err := dbInstalled.CreatePackage(p)
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
solution, err := s.Uninstall(A, true)
|
solution, err := s.Uninstall(A, true, true)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
||||||
@@ -735,7 +828,7 @@ var _ = Describe("Solver", func() {
|
|||||||
_, err := dbInstalled.CreatePackage(p)
|
_, err := dbInstalled.CreatePackage(p)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
solution, err := s.Uninstall(A, true)
|
solution, err := s.Uninstall(A, true, true)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
||||||
@@ -760,7 +853,7 @@ var _ = Describe("Solver", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
|
||||||
solution, err := s.Uninstall(A, true)
|
solution, err := s.Uninstall(A, true, true)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
||||||
@@ -786,7 +879,7 @@ var _ = Describe("Solver", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
|
||||||
solution, err := s.Uninstall(A, true)
|
solution, err := s.Uninstall(A, true, true)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
Expect(solution).To(ContainElement(A.IsFlagged(false)))
|
||||||
|
@@ -70,7 +70,7 @@ testInstall() {
|
|||||||
|
|
||||||
|
|
||||||
testUnInstall() {
|
testUnInstall() {
|
||||||
luet uninstall --config $tmpdir/luet.yaml test/b
|
luet uninstall --full --config $tmpdir/luet.yaml test/b
|
||||||
installst=$?
|
installst=$?
|
||||||
assertEquals 'uninstall test successfully' "$installst" "0"
|
assertEquals 'uninstall test successfully' "$installst" "0"
|
||||||
assertTrue 'package uninstalled' "[ ! -e '$tmpdir/testrootfs/b' ]"
|
assertTrue 'package uninstalled' "[ ! -e '$tmpdir/testrootfs/b' ]"
|
||||||
|
Reference in New Issue
Block a user