summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2025-02-18 16:39:10 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2025-02-18 16:39:10 +0100
commitd2ce308082886c50d0ef47efa5a277370603fac1 (patch)
tree616fbd3d84e81c2a50cad68bab5f6538b683492c
parentf82dcd7e4ebb3f70d28e9feb3621676f8c0cc024 (diff)
parent815d5b01bf9be1d476b110050b20ae980c76d4a8 (diff)
Merge branch 'solver3'
-rw-r--r--apt-pkg/contrib/configuration.cc33
-rw-r--r--apt-pkg/contrib/configuration.h3
-rw-r--r--apt-pkg/depcache.cc42
-rw-r--r--apt-pkg/solver3.cc40
-rw-r--r--cmdline/apt-mark.cc36
-rw-r--r--test/integration/framework17
-rw-r--r--test/integration/solver3.broken1
7 files changed, 77 insertions, 95 deletions
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index 28cf3e480..cf72aa3d7 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -1226,3 +1226,36 @@ bool Configuration::MatchAgainstConfig::Match(char const * str) const
return false;
}
/*}}}*/
+// helper for Install-Recommends-Sections and Never-MarkAuto-Sections /*{{{*/
+static bool ConfigValueInSubTree(Configuration *config, const char *SubTree, std::string_view const needle)
+{
+ if (needle.empty())
+ return false;
+ Configuration::Item const *Opts = config->Tree(SubTree);
+ if (Opts != nullptr && Opts->Child != nullptr)
+ {
+ Opts = Opts->Child;
+ for (; Opts != nullptr; Opts = Opts->Next)
+ {
+ if (Opts->Value.empty())
+ continue;
+ if (needle == Opts->Value)
+ return true;
+ }
+ }
+ return false;
+}
+bool Configuration::SectionInSubTree(char const *const SubTree, std::string_view Needle)
+{
+ if (ConfigValueInSubTree(this, SubTree, Needle))
+ return true;
+ auto const sub = Needle.rfind('/');
+ if (sub == std::string_view::npos)
+ {
+ std::string special{"/"};
+ special.append(Needle);
+ return ConfigValueInSubTree(this, SubTree, special);
+ }
+ return ConfigValueInSubTree(this, SubTree, Needle.substr(sub + 1));
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
index 4a21d977b..30a1cbf43 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -117,6 +117,9 @@ class APT_PUBLIC Configuration
void Dump(std::ostream& str, char const * const root,
char const * const format, bool const emptyValue);
+#ifdef APT_COMPILING_APT
+ bool SectionInSubTree(char const *const SubTree, std::string_view Needle);
+#endif
explicit Configuration(const Item *Root);
Configuration();
~Configuration();
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index b66f2bc66..970b4c01d 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -68,40 +68,6 @@ class DefaultRootSetFunc2 : public pkgDepCache::DefaultRootSetFunc
};
/*}}}*/
-// helper for Install-Recommends-Sections and Never-MarkAuto-Sections /*{{{*/
-// FIXME: Has verbatim copy in cmdline/apt-mark.cc
-static bool ConfigValueInSubTree(const char* SubTree, std::string_view const needle)
-{
- if (needle.empty())
- return false;
- Configuration::Item const *Opts = _config->Tree(SubTree);
- if (Opts != nullptr && Opts->Child != nullptr)
- {
- Opts = Opts->Child;
- for (; Opts != nullptr; Opts = Opts->Next)
- {
- if (Opts->Value.empty())
- continue;
- if (needle == Opts->Value)
- return true;
- }
- }
- return false;
-}
-static bool SectionInSubTree(char const * const SubTree, std::string_view Needle)
-{
- if (ConfigValueInSubTree(SubTree, Needle))
- return true;
- auto const sub = Needle.rfind('/');
- if (sub == std::string_view::npos)
- {
- std::string special{"/"};
- special.append(Needle);
- return ConfigValueInSubTree(SubTree, special);
- }
- return ConfigValueInSubTree(SubTree, Needle.substr(sub + 1));
-}
- /*}}}*/
pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) : /*{{{*/
d(NULL), cache(cache), released(false)
{
@@ -1068,7 +1034,7 @@ bool pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
// We do not check for or-groups here as we don't know which package takes care of
// providing the feature the user likes e.g.: browser1 | browser2 | browser3
// Temporary removals are effected by this as well, which is bad, but unlikely in practice
- bool const PinNeverMarkAutoSection = (PV->Section != 0 && SectionInSubTree("APT::Never-MarkAuto-Sections", PV.Section()));
+ bool const PinNeverMarkAutoSection = (PV->Section != 0 && _config->SectionInSubTree("APT::Never-MarkAuto-Sections", PV.Section()));
if (PinNeverMarkAutoSection)
{
for (DepIterator D = PV.DependsList(); D.end() != true; ++D)
@@ -1782,8 +1748,8 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg, bool AutoInst,
VerIterator const CurVer = Pkg.CurrentVer();
if (not CurVer.end() && CurVer->Section != 0 && strcmp(CurVer.Section(), PV.Section()) != 0)
{
- bool const CurVerInMoveSection = SectionInSubTree("APT::Move-Autobit-Sections", CurVer.Section());
- bool const InstVerInMoveSection = SectionInSubTree("APT::Move-Autobit-Sections", PV.Section());
+ bool const CurVerInMoveSection = _config->SectionInSubTree("APT::Move-Autobit-Sections", CurVer.Section());
+ bool const InstVerInMoveSection = _config->SectionInSubTree("APT::Move-Autobit-Sections", PV.Section());
return (not CurVerInMoveSection && InstVerInMoveSection);
}
return false;
@@ -2275,7 +2241,7 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator const &Dep) const
// FIXME: this is a meant as a temporary solution until the
// recommends are cleaned up
const char *sec = Dep.ParentVer().Section();
- if (sec && SectionInSubTree("APT::Install-Recommends-Sections", sec))
+ if (sec && _config->SectionInSubTree("APT::Install-Recommends-Sections", sec))
return true;
}
else if(Dep->Type == pkgCache::Dep::Suggests)
diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc
index c4fb567e1..7117296ab 100644
--- a/apt-pkg/solver3.cc
+++ b/apt-pkg/solver3.cc
@@ -673,8 +673,6 @@ void APT::Solver::Push(Work work)
choices.push_back(solved.size());
solved.push_back(Solved{Var(), std::move(work)});
- // Pop() will call MergeWithStack() when reverting to level 0, or RevertToStack after dumping to the debug log.
- _error->PushToStack();
}
void APT::Solver::UndoOne()
@@ -713,15 +711,15 @@ bool APT::Solver::Pop()
if (depth() == 0)
return false;
- if (unlikely(debug >= 2))
- for (std::string msg; _error->PopMessage(msg);)
- std::cerr << "Branch failed: " << msg << std::endl;
-
time_t now = time(nullptr);
if (now - startTime >= Timeout)
return _error->Error("Solver timed out.");
- _error->RevertToStack();
+ if (unlikely(debug >= 2))
+ for (std::string msg; _error->PopMessage(msg);)
+ std::cerr << "Branch failed: " << msg << std::endl;
+
+ _error->Discard();
assert(choices.back() < solved.size());
int itemsToUndo = solved.size() - choices.back();
@@ -781,6 +779,8 @@ bool APT::Solver::AddWork(Work &&w)
bool APT::Solver::Solve()
{
+ _error->PushToStack();
+ DEFER([&]() { _error->MergeWithStack(); });
startTime = time(nullptr);
while (true)
{
@@ -975,6 +975,7 @@ bool APT::Solver::FromDepCache(pkgDepCache &depcache)
bool APT::Solver::ToDepCache(pkgDepCache &depcache) const
{
+ FastContiguousCacheMap<pkgCache::Package, bool> movedManual(cache);
pkgDepCache::ActionGroup group(depcache);
for (auto P = cache.PkgBegin(); not P.end(); P++)
{
@@ -994,10 +995,31 @@ bool APT::Solver::ToDepCache(pkgDepCache &depcache) const
if (cand != P.CurrentVer())
{
+ bool automatic = (not reason.empty() || (depcache[P].Flags & pkgCache::Flag::Auto)) && not movedManual[P];
depcache.SetCandidateVersion(cand);
- depcache.MarkInstall(P, false, 0, reason.empty() && not(depcache[P].Flags & pkgCache::Flag::Auto));
+ depcache.MarkInstall(P, false, 0, not automatic);
+
+ // Set the automatic bit for new packages or move it on upgrades to oldlibs
if (not P->CurrentVer)
- depcache.MarkAuto(P, not reason.empty());
+ depcache.MarkAuto(P, automatic);
+ else if (not(depcache[P].Flags & pkgCache::Flag::Auto) && P.CurrentVer()->Section && cand->Section && not _config->SectionInSubTree("APT::Move-Autobit-Sections", P.CurrentVer().Section()) && _config->SectionInSubTree("APT::Move-Autobit-Sections", cand.Section()))
+ {
+ bool moved = false;
+ for (auto const &clause : (*this)[cand].clauses)
+ for (auto sol : clause->solutions)
+ {
+ // New installs move the auto-bit. TODO: Should we look at whether clause is the reason for installing it?
+ if (sol.CastPkg(cache) == P || sol.CastPkg(cache)->CurrentVer)
+ continue;
+ std::cerr << "Move manual bit from " << P.FullName() << " to " << sol.CastPkg(cache).Name() << std::endl;
+ movedManual[sol.CastPkg(cache)] = true;
+ depcache.MarkAuto(sol.CastPkg(cache), false);
+ moved = true;
+ }
+ if (moved)
+ depcache.MarkAuto(P, true);
+ }
+
}
else
depcache.MarkKeep(P, false, reason.empty() && not(depcache[P].Flags & pkgCache::Flag::Auto));
diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc
index 33716bb3c..180247cd0 100644
--- a/cmdline/apt-mark.cc
+++ b/cmdline/apt-mark.cc
@@ -139,40 +139,6 @@ static bool DoMarkAuto(CommandLine &CmdL)
return true;
}
/*}}}*/
-// helper for Install-Recommends-Sections and Never-MarkAuto-Sections /*{{{*/
-// FIXME: Copied verbatim from apt-pkg/depcache.cc
-static bool ConfigValueInSubTree(const char* SubTree, std::string_view const needle)
-{
- if (needle.empty())
- return false;
- Configuration::Item const *Opts = _config->Tree(SubTree);
- if (Opts != nullptr && Opts->Child != nullptr)
- {
- Opts = Opts->Child;
- for (; Opts != nullptr; Opts = Opts->Next)
- {
- if (Opts->Value.empty())
- continue;
- if (needle == Opts->Value)
- return true;
- }
- }
- return false;
-}
-static bool SectionInSubTree(char const * const SubTree, std::string_view Needle)
-{
- if (ConfigValueInSubTree(SubTree, Needle))
- return true;
- auto const sub = Needle.rfind('/');
- if (sub == std::string_view::npos)
- {
- std::string special{"/"};
- special.append(Needle);
- return ConfigValueInSubTree(SubTree, special);
- }
- return ConfigValueInSubTree(SubTree, Needle.substr(sub + 1));
-}
- /*}}}*/
/* DoMinimize - minimize manually installed {{{*/
/* Traverses dependencies of meta packages and marks them as manually
* installed. */
@@ -192,7 +158,7 @@ static bool DoMinimize(CommandLine &CmdL)
auto ver = pkg.CurrentVer();
return ver.end() == false && ((*DepCache)[pkg].Flags & pkgCache::Flag::Auto) == 0 &&
ver->Section != 0 &&
- SectionInSubTree("APT::Never-MarkAuto-Sections", ver.Section());
+ _config->SectionInSubTree("APT::Never-MarkAuto-Sections", ver.Section());
};
APT::PackageSet roots;
diff --git a/test/integration/framework b/test/integration/framework
index 3784ece06..35c1a1032 100644
--- a/test/integration/framework
+++ b/test/integration/framework
@@ -1555,22 +1555,15 @@ downloadfile() {
fi
}
-cleanup_solver3_pipe() {
- if [ "$APT_SOLVER" != "3.0" ]; then
- cat
- else
- # FIXME: We do not have support for listing autoremovals yet.
- # FIXME: Progress output is different
- sed -e '/Solving dependencies\.\.\./ d' \
- -e "/no longer required[.:]$/,/^Use '.* autoremove'/ d"
- fi
-}
cleanup_output() {
cat "$1" | sed \
-e '/gpgv: WARNING: This key is not suitable for signing in --compliance=gnupg mode/ d' \
-e '/^profiling:/ d' \
- | sed -e '/\.\.\.profiling:/ {N;s#\.\.\.profiling:.*\n#...#g}' \
- | cleanup_solver3_pipe \
+ -e '/\.\.\.profiling:/ {N;s#\.\.\.profiling:.*\n#...#g}' \
+ -e '/^Solving dependencies\.\.\.$/ d' \
+ -e '/^Calculating upgrade\.\.\.$/ d' \
+ -e 's/Solving dependencies\.\.\.//' \
+ -e 's/Calculating upgrade\.\.\.//' \
>"$2"
}
diff --git a/test/integration/solver3.broken b/test/integration/solver3.broken
index 2ad00555b..4a4e1532b 100644
--- a/test/integration/solver3.broken
+++ b/test/integration/solver3.broken
@@ -1,7 +1,6 @@
test-allow-scores-for-all-dependency-types # TBD: We are lacking single-sided conflicts preferences
test-apt-get-upgrade-by-source # TBD: Upgrading by source is not supported yet, mostly same issue as above
test-apt-install-order-matters-a-bit # Wontfix: Cannot fix, the order is not recorded in the depcache
-test-apt-move-and-forget-manual-sections # TBD: Moving the auto bit is not implemented
test-bug-470115-new-and-tighten-recommends # TBD: Calculation of what is already satisfied Recommends is broken
test-prevent-markinstall-multiarch-same-versionscrew # TBD: We consider the skewed ones obsolete and remove them...
test-resolve-by-keep-new-recommends # TBD: Fixing this seems to break test-bug-591882-conkeror, why?