diff options
author | David Kalnischkies <david@kalnischkies.de> | 2020-04-25 10:00:34 +0200 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2020-04-26 18:35:34 +0200 |
commit | aa7d2f55a0b0d683fbcd46d2a80c99957b788c3a (patch) | |
tree | 97b93aad85f7d716503ffafeff2c5448d0b569bc | |
parent | 9064a832bf2f02e2fd26c62ee867dd779797235a (diff) |
Discard impossible candidate versions also for non-installed
We reseted the candidate for installed packages back to the version
which is installed if one of the (critical) dependencies of it is not
statisfiable, but we can do the same for non-installed packages by
discarding the candidate which beside slightly helping the resolver also
improves error messages generated by apt as a sideeffect.
-rw-r--r-- | apt-pkg/depcache.cc | 47 | ||||
-rwxr-xr-x | test/integration/test-bug-735967-lib32-to-i386-unavailable | 2 |
2 files changed, 22 insertions, 27 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 052e3de0e..d43c1522e 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1399,45 +1399,40 @@ bool pkgDepCache::IsInstallOkDependenciesSatisfiableByCandidates(PkgIterator con for (DepIterator Dep = CandVer.DependsList(); Dep.end() != true;) { - // Grok or groups DepIterator Start = Dep; - bool Result = true; + bool foundSolution = false; unsigned Ors = 0; - for (bool LastOR = true; Dep.end() == false && LastOR == true; ++Dep, ++Ors) + // Is it possible to statisfy this dependency? + for (bool LastOR = true; not Dep.end() && LastOR; ++Dep, ++Ors) { LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or; - if ((DepState[Dep->ID] & DepInstall) == DepInstall) - Result = false; + if ((DepState[Dep->ID] & (DepInstall | DepCVer)) != 0) + foundSolution = true; } - if (Start.IsCritical() == false || Start.IsNegative() == true || Result == false) + if (foundSolution || not Start.IsCritical() || Start.IsNegative()) continue; - /* If we are in an or group locate the first or that can succeed. - We have already cached this… */ - for (; Ors > 1 && (DepState[Start->ID] & DepCVer) != DepCVer; --Ors) - ++Start; + if (DebugAutoInstall == true) + std::clog << OutputInDepth(Depth) << APT::PrettyDep(this, Start) << " can't be satisfied!" << std::endl; - if (Ors == 1 && (DepState[Start->ID] &DepCVer) != DepCVer) + // the dependency is critical, but can't be installed, so discard the candidate + // as the problemresolver will trip over it otherwise trying to install it (#735967) + StateCache &State = PkgState[Pkg->ID]; + if (not State.Protect()) { - if (DebugAutoInstall == true) - std::clog << OutputInDepth(Depth) << APT::PrettyDep(this, Start) << " can't be satisfied!" << std::endl; - - // the dependency is critical, but can't be installed, so discard the candidate - // as the problemresolver will trip over it otherwise trying to install it (#735967) - if (Pkg->CurrentVer != 0 && (PkgState[Pkg->ID].iFlags & Protected) != Protected) - { + if (Pkg->CurrentVer != 0) SetCandidateVersion(Pkg.CurrentVer()); - StateCache &State = PkgState[Pkg->ID]; - if (State.Mode != ModeDelete) - { - State.Mode = ModeKeep; - State.Update(Pkg, *this); - } - } - return false; + else + State.CandidateVer = nullptr; + if (not State.Delete()) + { + State.Mode = ModeKeep; + State.Update(Pkg, *this); + } } + return false; } return true; diff --git a/test/integration/test-bug-735967-lib32-to-i386-unavailable b/test/integration/test-bug-735967-lib32-to-i386-unavailable index 3b705d5f9..16aee4340 100755 --- a/test/integration/test-bug-735967-lib32-to-i386-unavailable +++ b/test/integration/test-bug-735967-lib32-to-i386-unavailable @@ -52,7 +52,7 @@ or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: - foo : Depends: libfoo but it is not going to be installed + foo : Depends: libfoo but it is not installable E: Unable to correct problems, you have held broken packages.' aptget install foo -s # activate multiarch |