diff options
author | Michael Vogt <mvo@debian.org> | 2014-03-27 15:20:49 +0100 |
---|---|---|
committer | Michael Vogt <mvo@debian.org> | 2014-03-27 15:20:49 +0100 |
commit | 355a960dd8bfbe2606be95d38aafd6bc0675d76f (patch) | |
tree | 67c58c736cee0f96f65b3de5e1070e1e1af92672 /apt-pkg/depcache.cc | |
parent | fa211e2d3b0305cfdd184cdba9750259f6d9c98e (diff) | |
parent | 62f1ee1cc7a5e16ca0cbfbee3c00cefab1892f87 (diff) |
Merge branch 'debian/sid' into feature/more-fancy-progress
Diffstat (limited to 'apt-pkg/depcache.cc')
-rw-r--r-- | apt-pkg/depcache.cc | 90 |
1 files changed, 66 insertions, 24 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index e2c412757..19a6e0d7e 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1059,10 +1059,9 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, return true; } - // check if we are allowed to install the package (if we haven't already) - if (P.Mode != ModeInstall || P.InstallVer != P.CandidateVer) - if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false) - return false; + // check if we are allowed to install the package + if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false) + return false; ActionGroup group(*this); P.iFlags &= ~AutoKept; @@ -1123,32 +1122,22 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, continue; /* Check if this dep should be consider for install. If it is a user - defined important dep and we are installed a new package then + defined important dep and we are installed a new package then it will be installed. Otherwise we only check for important - deps that have changed from the installed version - */ + deps that have changed from the installed version */ if (IsImportantDep(Start) == false) continue; - /* If we are in an or group locate the first or that can - succeed. We have already cached this.. */ + /* 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; + + /* unsatisfiable dependency: IsInstallOkDependenciesSatisfiableByCandidates + would have prevented us to get here if not overridden, so just skip + over the problem here as the frontend will know what it is doing */ if (Ors == 1 && (DepState[Start->ID] &DepCVer) != DepCVer && Start.IsNegative() == false) - { - if(DebugAutoInstall == true) - std::clog << OutputInDepth(Depth) << Start << " can't be satisfied!" << std::endl; - if (Start.IsCritical() == false) - continue; - // if the dependency was critical, we have absolutely no chance to install it, - // so if it wasn't installed remove it again. If it was, discard the candidate - // as the problemresolver will trip over it otherwise trying to install it (#735967) - if (Pkg->CurrentVer == 0) - MarkDelete(Pkg,false,Depth + 1, false); - else - SetCandidateVersion(Pkg.CurrentVer()); - return false; - } + continue; /* Check if any ImportantDep() (but not Critical) were added * since we installed the package. Also check for deps that @@ -1300,7 +1289,8 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst, unsigned long Depth, bool FromUser) { - return IsInstallOkMultiArchSameVersionSynced(Pkg,AutoInst, Depth, FromUser); + return IsInstallOkMultiArchSameVersionSynced(Pkg,AutoInst, Depth, FromUser) && + IsInstallOkDependenciesSatisfiableByCandidates(Pkg,AutoInst, Depth, FromUser); } bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg, bool const /*AutoInst*/, unsigned long const Depth, bool const FromUser) @@ -1308,6 +1298,11 @@ bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg, if (FromUser == true) // as always: user is always right return true; + // if we have checked before and it was okay, it will still be okay + if (PkgState[Pkg->ID].Mode == ModeInstall && + PkgState[Pkg->ID].InstallVer == PkgState[Pkg->ID].CandidateVer) + return true; + // ignore packages with none-M-A:same candidates VerIterator const CandVer = PkgState[Pkg->ID].CandidateVerIter(*this); if (unlikely(CandVer.end() == true) || CandVer == Pkg.CurrentVer() || @@ -1340,6 +1335,53 @@ bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg, return true; } +bool pkgDepCache::IsInstallOkDependenciesSatisfiableByCandidates(PkgIterator const &Pkg, + bool const AutoInst, unsigned long const Depth, bool const /*FromUser*/) +{ + if (AutoInst == false) + return true; + + VerIterator const CandVer = PkgState[Pkg->ID].CandidateVerIter(*this); + if (unlikely(CandVer.end() == true) || CandVer == Pkg.CurrentVer()) + return true; + + for (DepIterator Dep = CandVer.DependsList(); Dep.end() != true;) + { + // Grok or groups + DepIterator Start = Dep; + bool Result = true; + unsigned Ors = 0; + for (bool LastOR = true; Dep.end() == false && LastOR == true; ++Dep, ++Ors) + { + LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or; + + if ((DepState[Dep->ID] & DepInstall) == DepInstall) + Result = false; + } + + if (Start.IsCritical() == false || Start.IsNegative() == true || Result == false) + 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 (Ors == 1 && (DepState[Start->ID] &DepCVer) != DepCVer) + { + if (DebugAutoInstall == true) + std::clog << OutputInDepth(Depth) << 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) + SetCandidateVersion(Pkg.CurrentVer()); + return false; + } + } + + return true; +} /*}}}*/ // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/ // --------------------------------------------------------------------- |