From 99055353a54094034c8a526aa336cd59a039676c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 17 Jun 2014 13:47:01 +0200 Subject: don't send pkg from an unknown architecture via EDSP APT's cache can include packages from architectures dpkg has no knowledge about and can therefore not be installed for e.g. to allow easy lookups. There is no point in telling external solvers about them though and some of them might even be really talkative about ignoring them if we do. --- apt-pkg/edsp.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index 6d1b68c23..0d0418e06 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -50,7 +51,12 @@ bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress) if (Progress != NULL) Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver")); unsigned long p = 0; + std::vector archs = APT::Configuration::getArchitectures(); for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) + { + std::string const arch = Pkg.Arch(); + if (std::find(archs.begin(), archs.end(), arch) == archs.end()) + continue; for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver, ++p) { WriteScenarioVersion(Cache, output, Pkg, Ver); @@ -59,6 +65,7 @@ bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress) if (Progress != NULL && p % 100 == 0) Progress->Progress(p); } + } return true; } /*}}}*/ -- cgit v1.2.3-70-g09d2 From 224dc038412459a5f64d4e7a16845847b7797a67 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 17 Jun 2014 16:55:19 +0200 Subject: fix SubstVar to be usable as a replace_all method The name suggests that it is supposed to substitute a variable with a value, but we tend to use it in a more liberal replace_all() fashion, but this breaks if either of the parameters is empty or more importantly if two "variable" occurrences follow each other directly. --- apt-pkg/contrib/strutl.cc | 21 ++++++++++++++------- test/libapt/strutil_test.cc | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 2100ee47b..ce69c7a02 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -434,23 +434,30 @@ string TimeToStr(unsigned long Sec) /* This replaces all occurrences of Subst with Contents in Str. */ string SubstVar(const string &Str,const string &Subst,const string &Contents) { + if (Subst.empty() == true) + return Str; + string::size_type Pos = 0; string::size_type OldPos = 0; string Temp; - - while (OldPos < Str.length() && + + while (OldPos < Str.length() && (Pos = Str.find(Subst,OldPos)) != string::npos) { - Temp += string(Str,OldPos,Pos) + Contents; - OldPos = Pos + Subst.length(); + if (OldPos != Pos) + Temp.append(Str, OldPos, Pos - OldPos); + if (Contents.empty() == false) + Temp.append(Contents); + OldPos = Pos + Subst.length(); } - + if (OldPos == 0) return Str; - + + if (OldPos >= Str.length()) + return Temp; return Temp + string(Str,OldPos); } - string SubstVar(string Str,const struct SubstVar *Vars) { for (; Vars->Subst != 0; Vars++) diff --git a/test/libapt/strutil_test.cc b/test/libapt/strutil_test.cc index bc004fd66..e9b778c6b 100644 --- a/test/libapt/strutil_test.cc +++ b/test/libapt/strutil_test.cc @@ -70,3 +70,38 @@ TEST(StrUtilTest,EndsWith) EXPECT_FALSE(Endswith("abcd", "x")); EXPECT_FALSE(Endswith("abcd", "abcndefg")); } +TEST(StrUtilTest,SubstVar) +{ + EXPECT_EQ("", SubstVar("", "fails", "passes")); + EXPECT_EQ("test ", SubstVar("test fails", "fails", "")); + EXPECT_EQ("test passes", SubstVar("test passes", "", "fails")); + + EXPECT_EQ("test passes", SubstVar("test passes", "fails", "passes")); + EXPECT_EQ("test passes", SubstVar("test fails", "fails", "passes")); + + EXPECT_EQ("starts with", SubstVar("beginnt with", "beginnt", "starts")); + EXPECT_EQ("beginnt with", SubstVar("starts with", "starts", "beginnt")); + EXPECT_EQ("is in middle", SubstVar("is in der middle", "in der", "in")); + EXPECT_EQ("is in der middle", SubstVar("is in middle", "in", "in der")); + EXPECT_EQ("does end", SubstVar("does enden", "enden", "end")); + EXPECT_EQ("does enden", SubstVar("does end", "end", "enden")); + + EXPECT_EQ("abc", SubstVar("abc", "d", "a")); + EXPECT_EQ("abc", SubstVar("abd", "d", "c")); + EXPECT_EQ("abc", SubstVar("adc", "d", "b")); + EXPECT_EQ("abc", SubstVar("dbc", "d", "a")); + + EXPECT_EQ("b", SubstVar("b", "aa", "a")); + EXPECT_EQ("bb", SubstVar("bb", "aa", "a")); + EXPECT_EQ("bbb", SubstVar("bbb", "aa", "a")); + + EXPECT_EQ("aa", SubstVar("aaaa", "aa", "a")); + EXPECT_EQ("aaaa", SubstVar("aa", "a", "aa")); + EXPECT_EQ("aaaa", SubstVar("aaaa", "a", "a")); + EXPECT_EQ("a a a a ", SubstVar("aaaa", "a", "a ")); + + EXPECT_EQ(" bb bb bb bb ", SubstVar(" a a a a ", "a", "bb")); + EXPECT_EQ(" bb bb bb bb ", SubstVar(" aaa aaa aaa aaa ", "aaa", "bb")); + EXPECT_EQ(" bb a bb a bb a bb ", SubstVar(" aaa a aaa a aaa a aaa ", "aaa", "bb")); + +} -- cgit v1.2.3-70-g09d2 From 172947cd7dc5c88c94c6ad269dc6c6be002ee958 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 17 Jun 2014 19:05:53 +0200 Subject: do not call resolver twice on (dist-)upgrade --- apt-pkg/upgrade.cc | 6 ++++++ apt-private/private-install.cc | 22 ++++++++++++++++------ apt-private/private-install.h | 4 ++-- apt-private/private-upgrade.cc | 12 ++---------- .../test-external-dependency-solver-protocol | 6 ++++++ 5 files changed, 32 insertions(+), 18 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/upgrade.cc b/apt-pkg/upgrade.cc index 7926845c2..29b11937b 100644 --- a/apt-pkg/upgrade.cc +++ b/apt-pkg/upgrade.cc @@ -143,6 +143,12 @@ static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache) */ static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache) { + std::string const solver = _config->Find("APT::Solver", "internal"); + if (solver != "internal") { + OpTextProgress Prog(*_config); + return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog); + } + pkgDepCache::ActionGroup group(Cache); pkgProblemResolver Fix(&Cache); diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc index a365d4294..e08cd8057 100644 --- a/apt-private/private-install.cc +++ b/apt-private/private-install.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -524,15 +525,14 @@ static bool DoAutomaticRemove(CacheFile &Cache) static const unsigned short MOD_REMOVE = 1; static const unsigned short MOD_INSTALL = 2; -bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache) +bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, int UpgradeMode) { std::map verset; - return DoCacheManipulationFromCommandLine(CmdL, Cache, verset); + return DoCacheManipulationFromCommandLine(CmdL, Cache, verset, UpgradeMode); } bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, - std::map &verset) + std::map &verset, int UpgradeMode) { - // Enter the special broken fixing mode if the user specified arguments bool BrokenFix = false; if (Cache->BrokenCount() != 0) @@ -617,7 +617,17 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, if (Fix != NULL) { // Call the scored problem resolver - if (Fix->Resolve(true) == false && Cache->BrokenCount() == 0) + bool resolver_fail = false; + if (UpgradeMode == 0) + { + if (strcmp(CmdL.FileList[0], "dist-upgrade") == 0 || strcmp(CmdL.FileList[0], "full-upgrade") == 0) + resolver_fail = APT::Upgrade::Upgrade(Cache, 0); + else + resolver_fail = Fix->Resolve(true); + } else + resolver_fail = APT::Upgrade::Upgrade(Cache, UpgradeMode); + + if (resolver_fail == false && Cache->BrokenCount() == 0) return false; } @@ -676,7 +686,7 @@ bool DoInstall(CommandLine &CmdL) std::map verset; - if(!DoCacheManipulationFromCommandLine(CmdL, Cache, verset)) + if(!DoCacheManipulationFromCommandLine(CmdL, Cache, verset, 0)) return false; /* Print out a list of packages that are going to be installed extra diff --git a/apt-private/private-install.h b/apt-private/private-install.h index 828163e40..8daa4a776 100644 --- a/apt-private/private-install.h +++ b/apt-private/private-install.h @@ -21,8 +21,8 @@ class pkgProblemResolver; APT_PUBLIC bool DoInstall(CommandLine &Cmd); bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, - std::map &verset); -bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache); + std::map &verset, int UpgradeMode); +bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, int UpgradeMode); APT_PUBLIC bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, bool Safety = true); diff --git a/apt-private/private-upgrade.cc b/apt-private/private-upgrade.cc index 68b2c5e00..31f067576 100644 --- a/apt-private/private-upgrade.cc +++ b/apt-private/private-upgrade.cc @@ -23,18 +23,10 @@ static bool UpgradeHelper(CommandLine &CmdL, int UpgradeFlags) return false; c0out << _("Calculating upgrade... ") << std::flush; - if (APT::Upgrade::Upgrade(Cache, UpgradeFlags) == false) - { - c0out << _("Failed") << std::endl; - ShowBroken(c1out,Cache,false); - return _error->Error(_("Internal error, Upgrade broke stuff")); - } + if(!DoCacheManipulationFromCommandLine(CmdL, Cache, UpgradeFlags)) + return false; c0out << _("Done") << std::endl; - // parse additional cmdline pkg manipulation switches - if(!DoCacheManipulationFromCommandLine(CmdL, Cache)) - return false; - return InstallPackages(Cache,true); } diff --git a/test/integration/test-external-dependency-solver-protocol b/test/integration/test-external-dependency-solver-protocol index 09230d383..07d2441b6 100755 --- a/test/integration/test-external-dependency-solver-protocol +++ b/test/integration/test-external-dependency-solver-protocol @@ -51,6 +51,12 @@ rm -f /tmp/dump.edsp testfailure aptget install --solver dump awesomecoolstuff:i386 -s testsuccess test -s /tmp/dump.edsp +testsuccess aptget dist-upgrade -s +testsuccess aptget dist-upgrade -s --solver apt + +testsuccess aptget upgrade -s +testsuccess aptget upgrade -s --solver apt + configarchitecture 'armel' msgtest 'Test direct calling is okay for' 'apt-internal-solver' cat /tmp/dump.edsp | aptinternalsolver > solver.result 2>&1 || true -- cgit v1.2.3-70-g09d2