From 24d05892fe96d52aaceef7af94d0e444e140067c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 18 Jun 2014 08:25:16 +0200 Subject: Tell the user if no updates are available after apt update Thanks to Jakub Wilk for the suggestion. Closes: #751388 --- apt-private/private-update.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apt-private/private-update.cc b/apt-private/private-update.cc index fa827dea4..a843d6f86 100644 --- a/apt-private/private-update.cc +++ b/apt-private/private-update.cc @@ -90,7 +90,10 @@ bool DoUpdate(CommandLine &CmdL) "%i package can be upgraded. Run 'apt list --upgradable' to see it.\n", "%i packages can be upgraded. Run 'apt list --upgradable' to see them.\n", upgradable); - ioprintf(c1out, msg, upgradable); + if (upgradable == 0) + c1out << _("All packages are up to date.") << std::endl; + else + ioprintf(c1out, msg, upgradable); } return true; -- cgit v1.2.3 From 037fada40db175e95f44c0cb039474c6dc518963 Mon Sep 17 00:00:00 2001 From: Konstantin Manna Date: Sun, 15 Jun 2014 00:53:04 +0200 Subject: fix two german manpage spelling mistakes Closes: 751635 --- doc/po/de.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/po/de.po b/doc/po/de.po index b048d9661..feeb7736e 100644 --- a/doc/po/de.po +++ b/doc/po/de.po @@ -726,7 +726,7 @@ msgid "" "installed instead of removed." msgstr "" "remove ist identisch mit install, mit " -"der Ausnahme, dass Pakte entfernt anstatt installiert werden. Beachten Sie, " +"der Ausnahme, dass Pakete entfernt anstatt installiert werden. Beachten Sie, " "dass das Entfernen von Paketen deren Konfigurationsdateien im System " "belässt. Wenn ein Pluszeichen an den Paketnamen angehängt wird (ohne " "Leerzeichen dazwischen) wird das erkannte Paket installiert anstatt entfernt." @@ -1051,7 +1051,7 @@ msgid "" "you wish to upgrade, and if a newer version is available, it (and its " "dependencies, as described above) will be downloaded and installed." msgstr "" -"Dies ist außerdem die bevorzugt zu benutzende Art, wenn Sie Sie ein Upgrade " +"Dies ist außerdem die bevorzugt zu benutzende Art, wenn Sie ein Upgrade " "eines oder mehrerer bereits installierter Pakete durchführen möchten, ohne " "ein Upgrade aller Pakete, die Sie auf Ihrem System haben, durchzuführen. " "Anders als das Ziel von »upgrade«, das die neusten Versionen aller aktuell " -- cgit v1.2.3 From 480c2414e72058b50fa287f779a4fda7b22e1018 Mon Sep 17 00:00:00 2001 From: Konstantin Manna Date: Sun, 15 Jun 2014 18:35:15 +0200 Subject: add missing comma in SEE ALSO of apt-secure manpage Closes: 748506 --- doc/apt-secure.8.xml | 2 +- doc/po/apt-doc.pot | 2 +- doc/po/de.po | 4 ++-- doc/po/es.po | 4 ++-- doc/po/fr.po | 4 ++-- doc/po/it.po | 4 ++-- doc/po/ja.po | 4 ++-- doc/po/pl.po | 4 ++-- doc/po/pt.po | 4 ++-- doc/po/pt_BR.po | 2 +- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/apt-secure.8.xml b/doc/apt-secure.8.xml index 981351615..15a73476d 100644 --- a/doc/apt-secure.8.xml +++ b/doc/apt-secure.8.xml @@ -193,7 +193,7 @@ See Also &apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, -&debsign; &debsig-verify;, &gpg; +&debsign;, &debsig-verify;, &gpg; For more background information you might want to review the diff --git a/doc/po/apt-doc.pot b/doc/po/apt-doc.pot index a058e6506..94ad1238d 100644 --- a/doc/po/apt-doc.pot +++ b/doc/po/apt-doc.pot @@ -2153,7 +2153,7 @@ msgstr "" #: apt-secure.8.xml:195 msgid "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" msgstr "" #. type: Content of: diff --git a/doc/po/de.po b/doc/po/de.po index feeb7736e..98bfcb6e4 100644 --- a/doc/po/de.po +++ b/doc/po/de.po @@ -3010,10 +3010,10 @@ msgstr "" #: apt-secure.8.xml:195 msgid "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" msgstr "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" #. type: Content of: #: apt-secure.8.xml:199 diff --git a/doc/po/es.po b/doc/po/es.po index 2cf3a070a..0b594afe9 100644 --- a/doc/po/es.po +++ b/doc/po/es.po @@ -3098,10 +3098,10 @@ msgstr "" #: apt-secure.8.xml:195 msgid "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" msgstr "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" #. type: Content of: #: apt-secure.8.xml:199 diff --git a/doc/po/fr.po b/doc/po/fr.po index 530de5046..0c69a1482 100644 --- a/doc/po/fr.po +++ b/doc/po/fr.po @@ -3022,10 +3022,10 @@ msgstr "" #: apt-secure.8.xml:195 msgid "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" msgstr "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" #. type: Content of: #: apt-secure.8.xml:199 diff --git a/doc/po/it.po b/doc/po/it.po index c5ef090ff..fc098a6ab 100644 --- a/doc/po/it.po +++ b/doc/po/it.po @@ -3033,10 +3033,10 @@ msgstr "" #: apt-secure.8.xml:195 msgid "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" msgstr "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" #. type: Content of: #: apt-secure.8.xml:199 diff --git a/doc/po/ja.po b/doc/po/ja.po index 2475b810d..5f127426a 100644 --- a/doc/po/ja.po +++ b/doc/po/ja.po @@ -2963,10 +2963,10 @@ msgstr "" #: apt-secure.8.xml:195 msgid "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" msgstr "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" #. type: Content of: #: apt-secure.8.xml:199 diff --git a/doc/po/pl.po b/doc/po/pl.po index 5f92c521c..66b494ff9 100644 --- a/doc/po/pl.po +++ b/doc/po/pl.po @@ -3131,10 +3131,10 @@ msgstr "" #: apt-secure.8.xml:195 msgid "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" msgstr "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" #. type: Content of: #: apt-secure.8.xml:199 diff --git a/doc/po/pt.po b/doc/po/pt.po index 6ebf93bc7..b67dc8b03 100644 --- a/doc/po/pt.po +++ b/doc/po/pt.po @@ -3042,10 +3042,10 @@ msgstr "" #: apt-secure.8.xml:195 msgid "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" msgstr "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" #. type: Content of: #: apt-secure.8.xml:199 diff --git a/doc/po/pt_BR.po b/doc/po/pt_BR.po index e9e785f08..b1df8a068 100644 --- a/doc/po/pt_BR.po +++ b/doc/po/pt_BR.po @@ -2159,7 +2159,7 @@ msgstr "" #: apt-secure.8.xml:195 msgid "" "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, " -"&debsign; &debsig-verify;, &gpg;" +"&debsign;, &debsig-verify;, &gpg;" msgstr "" #. type: Content of: -- cgit v1.2.3 From dab5f8745b8d6df1060490c8c5ac895832657a74 Mon Sep 17 00:00:00 2001 From: Fredrik Fornwall Date: Tue, 17 Jun 2014 11:33:00 +0200 Subject: use P_ instead of ngettext to compiling with --disable-nls Closes: 751857 --- apt-private/private-update.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apt-private/private-update.cc b/apt-private/private-update.cc index a843d6f86..0f2f7a8da 100644 --- a/apt-private/private-update.cc +++ b/apt-private/private-update.cc @@ -86,7 +86,7 @@ bool DoUpdate(CommandLine &CmdL) if (I->CurrentVer != 0 && state.Upgradable()) upgradable++; } - const char *msg = ngettext( + const char *msg = P_( "%i package can be upgraded. Run 'apt list --upgradable' to see it.\n", "%i packages can be upgraded. Run 'apt list --upgradable' to see them.\n", upgradable); -- cgit v1.2.3 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(+) 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 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(-) 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 From d39d7f885d61bfe296c131c83bdc042a2ab6b0d7 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 17 Jun 2014 17:45:33 +0200 Subject: show our broken packages message in 'apt' solver --- apt-private/private-output.cc | 204 ++++++++++++++++++++++------------------- apt-private/private-output.h | 3 +- cmdline/apt-internal-solver.cc | 24 +++-- cmdline/makefile | 20 ++-- 4 files changed, 134 insertions(+), 117 deletions(-) diff --git a/apt-private/private-output.cc b/apt-private/private-output.cc index 8f190a551..158bd5c71 100644 --- a/apt-private/private-output.cc +++ b/apt-private/private-output.cc @@ -344,129 +344,141 @@ bool ShowList(ostream &out,string Title,string List,string VersionsList) Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed Depends: libsasl7 but it is not going to be installed */ -void ShowBroken(ostream &out,CacheFile &Cache,bool Now) +static void ShowBrokenPackage(ostream &out, pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg, bool const Now) { - if (Cache->BrokenCount() == 0) + if (Now == true) + { + if ((*Cache)[Pkg].NowBroken() == false) + return; + } + else + { + if ((*Cache)[Pkg].InstBroken() == false) + return; + } + + // Print out each package and the failed dependencies + out << " " << Pkg.FullName(true) << " :"; + unsigned const Indent = Pkg.FullName(true).size() + 3; + bool First = true; + pkgCache::VerIterator Ver; + + if (Now == true) + Ver = Pkg.CurrentVer(); + else + Ver = (*Cache)[Pkg].InstVerIter(*Cache); + + if (Ver.end() == true) + { + out << endl; return; + } - out << _("The following packages have unmet dependencies:") << endl; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;) { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); // advances D + + if ((*Cache)->IsImportantDep(End) == false) + continue; + if (Now == true) { - if (Cache[I].NowBroken() == false) + if (((*Cache)[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow) continue; } else { - if (Cache[I].InstBroken() == false) + if (((*Cache)[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) continue; } - - // Print out each package and the failed dependencies - out << " " << I.FullName(true) << " :"; - unsigned const Indent = I.FullName(true).size() + 3; - bool First = true; - pkgCache::VerIterator Ver; - - if (Now == true) - Ver = I.CurrentVer(); - else - Ver = Cache[I].InstVerIter(Cache); - - if (Ver.end() == true) - { - out << endl; - continue; - } - - for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;) + + bool FirstOr = true; + while (1) { - // Compute a single dependency element (glob or) - pkgCache::DepIterator Start; - pkgCache::DepIterator End; - D.GlobOr(Start,End); // advances D + if (First == false) + for (unsigned J = 0; J != Indent; J++) + out << ' '; + First = false; - if (Cache->IsImportantDep(End) == false) - continue; - - if (Now == true) + if (FirstOr == false) { - if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow) - continue; + for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++) + out << ' '; } else + out << ' ' << End.DepType() << ": "; + FirstOr = false; + + out << Start.TargetPkg().FullName(true); + + // Show a quick summary of the version requirements + if (Start.TargetVer() != 0) + out << " (" << Start.CompType() << " " << Start.TargetVer() << ")"; + + /* Show a summary of the target package if possible. In the case + of virtual packages we show nothing */ + pkgCache::PkgIterator Targ = Start.TargetPkg(); + if (Targ->ProvidesList == 0) { - if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) - continue; - } - - bool FirstOr = true; - while (1) - { - if (First == false) - for (unsigned J = 0; J != Indent; J++) - out << ' '; - First = false; + out << ' '; + pkgCache::VerIterator Ver = (*Cache)[Targ].InstVerIter(*Cache); + if (Now == true) + Ver = Targ.CurrentVer(); - if (FirstOr == false) + if (Ver.end() == false) { - for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++) - out << ' '; + if (Now == true) + ioprintf(out,_("but %s is installed"),Ver.VerStr()); + else + ioprintf(out,_("but %s is to be installed"),Ver.VerStr()); } else - out << ' ' << End.DepType() << ": "; - FirstOr = false; - - out << Start.TargetPkg().FullName(true); - - // Show a quick summary of the version requirements - if (Start.TargetVer() != 0) - out << " (" << Start.CompType() << " " << Start.TargetVer() << ")"; - - /* Show a summary of the target package if possible. In the case - of virtual packages we show nothing */ - pkgCache::PkgIterator Targ = Start.TargetPkg(); - if (Targ->ProvidesList == 0) { - out << ' '; - pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache); - if (Now == true) - Ver = Targ.CurrentVer(); - - if (Ver.end() == false) + if ((*Cache)[Targ].CandidateVerIter(*Cache).end() == true) { - if (Now == true) - ioprintf(out,_("but %s is installed"),Ver.VerStr()); + if (Targ->ProvidesList == 0) + out << _("but it is not installable"); else - ioprintf(out,_("but %s is to be installed"),Ver.VerStr()); - } + out << _("but it is a virtual package"); + } else - { - if (Cache[Targ].CandidateVerIter(Cache).end() == true) - { - if (Targ->ProvidesList == 0) - out << _("but it is not installable"); - else - out << _("but it is a virtual package"); - } - else - out << (Now?_("but it is not installed"):_("but it is not going to be installed")); - } + out << (Now?_("but it is not installed"):_("but it is not going to be installed")); } - - if (Start != End) - out << _(" or"); - out << endl; - - if (Start == End) - break; - ++Start; - } - } - } + } + + if (Start != End) + out << _(" or"); + out << endl; + + if (Start == End) + break; + ++Start; + } + } +} +void ShowBroken(ostream &out, CacheFile &Cache, bool const Now) +{ + if (Cache->BrokenCount() == 0) + return; + + out << _("The following packages have unmet dependencies:") << endl; + for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + { + pkgCache::PkgIterator const I(Cache,Cache.List[J]); + ShowBrokenPackage(out, &Cache, I, Now); + } +} +void ShowBroken(ostream &out, pkgCacheFile &Cache, bool const Now) +{ + if (Cache->BrokenCount() == 0) + return; + + out << _("The following packages have unmet dependencies:") << endl; + for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg) + ShowBrokenPackage(out, &Cache, Pkg, Now); } /*}}}*/ // ShowNew - Show packages to newly install /*{{{*/ diff --git a/apt-private/private-output.h b/apt-private/private-output.h index 9633d0c37..6f3a964d7 100644 --- a/apt-private/private-output.h +++ b/apt-private/private-output.h @@ -28,7 +28,8 @@ void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records, // helper to describe global state -APT_PUBLIC void ShowBroken(std::ostream &out,CacheFile &Cache,bool Now); +APT_PUBLIC void ShowBroken(std::ostream &out, CacheFile &Cache, bool const Now); +APT_PUBLIC void ShowBroken(std::ostream &out, pkgCacheFile &Cache, bool const Now); APT_PUBLIC bool ShowList(std::ostream &out, std::string Title, std::string List, std::string VersionsList); diff --git a/cmdline/apt-internal-solver.cc b/cmdline/apt-internal-solver.cc index e4cdf6381..5fda7b6a0 100644 --- a/cmdline/apt-internal-solver.cc +++ b/cmdline/apt-internal-solver.cc @@ -24,9 +24,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -168,18 +170,20 @@ int main(int argc,const char *argv[]) /*{{{*/ EDSP::WriteProgress(60, "Call problemresolver on current scenario…", output); + std::string failure; if (upgrade == true) { - if (pkgAllUpgrade(CacheFile) == false) { - EDSP::WriteError("ERR_UNSOLVABLE_UPGRADE", "An upgrade error occurred", output); - return 0; - } + if (pkgAllUpgrade(CacheFile) == false) + failure = "ERR_UNSOLVABLE_UPGRADE"; } else if (distUpgrade == true) { - if (pkgDistUpgrade(CacheFile) == false) { - EDSP::WriteError("ERR_UNSOLVABLE_DIST_UPGRADE", "An dist-upgrade error occurred", output); - return 0; - } - } else if (Fix.Resolve() == false) { - EDSP::WriteError("ERR_UNSOLVABLE", "An error occurred", output); + if (pkgDistUpgrade(CacheFile) == false) + failure = "ERR_UNSOLVABLE_DIST_UPGRADE"; + } else if (Fix.Resolve() == false) + failure = "ERR_UNSOLVABLE"; + + if (failure.empty() == false) { + std::ostringstream broken; + ShowBroken(broken, CacheFile, false); + EDSP::WriteError(failure.c_str(), broken.str(), output); return 0; } diff --git a/cmdline/makefile b/cmdline/makefile index c4a249cd6..b7c35ddd1 100644 --- a/cmdline/makefile +++ b/cmdline/makefile @@ -8,49 +8,49 @@ include ../buildlib/defaults.mak # The apt program PROGRAM=apt SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt.cc include $(PROGRAM_H) # The apt-cache program PROGRAM=apt-cache SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-cache.cc include $(PROGRAM_H) # The apt-get program PROGRAM=apt-get SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-get.cc include $(PROGRAM_H) # The apt-config program PROGRAM=apt-config SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-config.cc include $(PROGRAM_H) # The apt-cdrom program PROGRAM=apt-cdrom SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-cdrom.cc include $(PROGRAM_H) # The apt-mark program PROGRAM=apt-mark SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-mark.cc include $(PROGRAM_H) # The apt-helper PROGRAM=apt-helper SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-helper.cc include $(PROGRAM_H) @@ -75,14 +75,14 @@ include $(PROGRAM_H) # The apt-extracttemplates program PROGRAM=apt-extracttemplates SLIBS = -lapt-pkg -lapt-inst $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +LIB_MAKES = apt-pkg/makefile apt-inst/makefile SOURCE = apt-extracttemplates.cc include $(PROGRAM_H) # The internal solver acting as an external PROGRAM=apt-internal-solver -SLIBS = -lapt-pkg $(INTLLIBS) -LIB_MAKES = apt-pkg/makefile +SLIBS = -lapt-pkg -lapt-private $(INTLLIBS) +LIB_MAKES = apt-pkg/makefile apt-private/makefile SOURCE = apt-internal-solver.cc include $(PROGRAM_H) -- cgit v1.2.3 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(-) 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 From 4010ee76cb1a771d57f1339df725e962df23900e Mon Sep 17 00:00:00 2001 From: Stefano Zacchiroli Date: Tue, 17 Jun 2014 17:03:27 +0200 Subject: EDSP doc: clarify that Install/Remove packages are arch-qualified --- doc/external-dependency-solver-protocol.txt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/doc/external-dependency-solver-protocol.txt b/doc/external-dependency-solver-protocol.txt index 790f2f1ee..eb7832120 100644 --- a/doc/external-dependency-solver-protocol.txt +++ b/doc/external-dependency-solver-protocol.txt @@ -5,6 +5,14 @@ external dependency solvers. The protocol is called APT EDSP, for "APT External Dependency Solver Protocol". +## Terminology + +In the following we use the term **architecture qualified package name** +(or *arch-qualified package names* for short) to refer to package +identifiers of the form "arch:package" where "arch" is a dpkg +architecture and "package" a dpkg package name. + + ## Components - **APT**: we know this one. @@ -132,9 +140,9 @@ The following **configuration fields** are supported in request stanzas: The following **action fields** are supported in request stanzas: - **Install:** (optional, defaults to the empty string) A space - separated list of package names, with *no version attached*, to - install. This field denotes a list of packages that the user wants to - install, usually via an APT `install` request. + separated list of arch-qualified package names, with *no version + attached*, to install. This field denotes a list of packages that the + user wants to install, usually via an APT `install` request. - **Remove:** (optional, defaults to the empty string) Same syntax of Install. This field denotes a list of packages that the user wants to @@ -201,7 +209,7 @@ field. The following fields are supported in package stanzas: - **APT-Candidate:** (optional, defaults to `no`). Allowed values: `yes`, `no`. When set to `yes`, the corresponding package is the APT candidate for installation among all available packages with the same - name. + name and with the same architecture. - **APT-Automatic:** (optional, defaults to `no`). Allowed values: `yes`, `no`. When set to `yes`, the corresponding package is marked by -- cgit v1.2.3 From 22c3ac52252b6eafe0d31485b18730cfb53a8dc3 Mon Sep 17 00:00:00 2001 From: Stefano Zacchiroli Date: Tue, 17 Jun 2014 17:04:09 +0200 Subject: EDSP doc: (minor) consistently use 2 blank lines before headings Git-Dch: Ignore --- doc/external-dependency-solver-protocol.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/external-dependency-solver-protocol.txt b/doc/external-dependency-solver-protocol.txt index eb7832120..7db1479b2 100644 --- a/doc/external-dependency-solver-protocol.txt +++ b/doc/external-dependency-solver-protocol.txt @@ -70,6 +70,7 @@ configuration documentation for more, and more up to date, information. - **Dir::Bin::Solvers**: absolute path of the directory where to look for external solvers. Defaults to `/usr/lib/apt/solvers`. + ## Protocol When configured to use an external solver, APT will resort to it to @@ -226,6 +227,7 @@ field. The following fields are supported in package stanzas: Release file entry (Origin, Label, Codename, etc.) in the format of APT_PREFERENCES(5). + ### Answer An answer from the external solver to APT is either a *solution* or an -- cgit v1.2.3 From 82ced5c894cd013721f432ae8da66114155e04c7 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 17 Jun 2014 19:25:03 +0200 Subject: EDSP doc: some typo and wording fixes Git-Dch: Ignore --- doc/external-dependency-solver-protocol.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/external-dependency-solver-protocol.txt b/doc/external-dependency-solver-protocol.txt index 7db1479b2..14e9528c8 100644 --- a/doc/external-dependency-solver-protocol.txt +++ b/doc/external-dependency-solver-protocol.txt @@ -9,8 +9,8 @@ External Dependency Solver Protocol". In the following we use the term **architecture qualified package name** (or *arch-qualified package names* for short) to refer to package -identifiers of the form "arch:package" where "arch" is a dpkg -architecture and "package" a dpkg package name. +identifiers of the form "package:arch" where "package" is a package name +and "arch" a dpkg architecture. ## Components @@ -210,7 +210,7 @@ field. The following fields are supported in package stanzas: - **APT-Candidate:** (optional, defaults to `no`). Allowed values: `yes`, `no`. When set to `yes`, the corresponding package is the APT candidate for installation among all available packages with the same - name and with the same architecture. + name and architecture. - **APT-Automatic:** (optional, defaults to `no`). Allowed values: `yes`, `no`. When set to `yes`, the corresponding package is marked by @@ -236,11 +236,11 @@ An answer from the external solver to APT is either a *solution* or an The following invariant on **exit codes** must hold true. When the external solver is *able to find a solution*, it will write the solution to standard output and then exit with an exit code of 0. When the -external solver is *unable to find a solution* (and s aware of that), it -will write an error to standard output and then exit with an exit code -of 0. An exit code other than 0 will be interpreted as a solver crash -with no meaningful error about dependency resolution to convey to the -user. +external solver is *unable to find a solution* (and is aware of that), +it will write an error to standard output and then exit with an exit +code of 0. An exit code other than 0 will be interpreted as a solver +crash with no meaningful error about dependency resolution to convey to +the user. #### Solution -- cgit v1.2.3