Apply apt-0.5.15lorg2-alt-versionmatch-TryToChangeVer.patch

Added in commit 6c2eeb8:
updated versionmatch/TryToChangeVer logic

My previous versionmatch.patch was half-way wrong and/or incomplete.
The problem was that pkgCache::VerIterator::CompareVer() does not
do full-blown version comparison, but rather something strange
(see apt-pkg/pkgcache.cc).

I also noticed that, while TryToInstall() does use Fix.ScoreSort,
TryToChangeVer() does not, which is probably wrong.

The solution is as follows:

1) pkgVersionMatch::FindAll() does not sort versions any longer;
it does not have sufficient information, such as Cache and Fix,
to sort the versions.

2) TryToChangeVer() calls FindAll() instead of Find() and uses
Fix.ScoreSort to sort the versions.  If Fix.ScoreSort returns 0,
it also tries Cache.VS().CmpVersion(), which is the right way to
reach rpmvercmp().

Also updated 'Selected version ... for ...' diagnostics.

(old result and message)
$ ~tmp/build/aptbox/apt-get --dry-run install python=2.4 2>&1 |grep ^Selected
Selected version 2.4.4-alt8 for python
$

The result was wrong, because I have a better version,
which is 2.4.4-alt8.1.

(new result and message)
$ ~tmp/build/aptbox/apt-get --dry-run install python=2.4 2>&1 |grep ^Selected
Selected version python-strict#2.4.4-alt8.1 for python=2.4
$

Update: also do not sort ascending and reverse the list, this is going
to break "stable sort" logic.  Just sort descending.

Update2: actually make CmpVersion() primarily sort condition and
Fix.ScoreSort secondary sort condition.  Fix.ScoreSort should not be
activated early, because e.g. for 'python-devel>=2.3' it is going to
select python2.3-dev, but I want python-dev#2.4.
This commit is contained in:
Gleb Fotengauer-Malinovskiy 2014-05-16 21:04:22 +04:00
parent 5c157e80d3
commit 3070a3cfb9
4 changed files with 134 additions and 271 deletions

View File

@ -1,254 +0,0 @@
--- apt-0.5.15lorg2/apt-pkg/versionmatch.cc- 2007-03-22 23:05:34 +0300
+++ apt-0.5.15lorg2/apt-pkg/versionmatch.cc 2007-03-22 23:05:34 +0300
@@ -164,11 +164,12 @@ bool pkgVersionMatch::MatchVer(const cha
// VersionMatch::Find - Locate the best match for the select type /*{{{*/
// ---------------------------------------------------------------------
/* */
-pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg)
+std::list<pkgCache::VerIterator> pkgVersionMatch::FindAll(pkgCache::PkgIterator Pkg)
{
// CNC:2003-11-05
pkgVersioningSystem *VS = Pkg.Cache()->VS;
pkgCache::VerIterator Ver = Pkg.VersionList();
+ std::list<pkgCache::VerIterator> found;
for (; Ver.end() == false; Ver++)
{
@@ -178,10 +179,10 @@ pkgCache::VerIterator pkgVersionMatch::F
if (VerPrefixMatch)
{
if (MatchVer(Ver.VerStr(),VerStr,VerPrefixMatch) == true)
- return Ver;
+ found.push_back(Ver);
} else {
if (VS->CheckDep(Ver.VerStr(),VerOp,VerStr.c_str()) == true)
- return Ver;
+ found.push_back(Ver);
}
continue;
@@ -189,8 +190,11 @@ pkgCache::VerIterator pkgVersionMatch::F
for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; VF++)
if (FileMatch(VF.File()) == true)
- return Ver;
+ found.push_back(Ver);
}
+
+ if (found.size() > 0)
+ goto done;
// CNC:2003-11-11 - Virtual package handling.
if (Type == Version)
@@ -205,15 +209,28 @@ pkgCache::VerIterator pkgVersionMatch::F
if (VerPrefixMatch || (HasRelease && strchr(PrvVerStr, '-') == NULL))
{
if (MatchVer(PrvVerStr,VerStr,VerPrefixMatch) == true)
- return Prv.OwnerVer();
+ found.push_back(Prv.OwnerVer());
} else {
if (VS->CheckDep(PrvVerStr,VerOp,VerStr.c_str()) == true)
- return Prv.OwnerVer();
+ found.push_back(Prv.OwnerVer());
}
}
}
- // This will be Ended by now.
+done:
+ return found;
+}
+
+pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg)
+{
+ std::list<pkgCache::VerIterator> found = FindAll(Pkg);
+ if (found.size() > 0)
+ return found.front();
+
+ // return "empty" iterator at its end
+ pkgCache::VerIterator Ver = Pkg.VersionList();
+ while (Ver.end() == false)
+ Ver++;
return Ver;
}
/*}}}*/
--- apt-0.5.15lorg2/apt-pkg/versionmatch.h- 2007-03-22 23:05:34 +0300
+++ apt-0.5.15lorg2/apt-pkg/versionmatch.h 2007-03-22 23:05:34 +0300
@@ -36,6 +36,7 @@
#endif
#include <string>
+#include <list>
#include <apt-pkg/pkgcache.h>
using std::string;
@@ -70,6 +71,7 @@ class pkgVersionMatch
// CNC:2003-11-05
pkgVersionMatch(string Data,MatchType Type,int Op=pkgCache::Dep::Equals);
+ std::list<pkgCache::VerIterator> FindAll(pkgCache::PkgIterator Pkg);
};
#endif
--- apt-0.5.15lorg2/cmdline/apt-get.cc- 2007-04-09 15:39:15 +0400
+++ apt-0.5.15lorg2/cmdline/apt-get.cc 2007-04-09 15:44:21 +0400
@@ -1528,17 +1528,64 @@ static const char *op2str(int op)
}
}
+// best versions go first
+class bestVersionOrder
+{
+ private:
+ pkgDepCache &Cache_;
+ pkgProblemResolver &Fix_;
+ public:
+ bestVersionOrder(pkgDepCache &Cache, pkgProblemResolver &Fix)
+ : Cache_(Cache), Fix_(Fix) { }
+ bool operator() (const pkgCache::VerIterator &a, const pkgCache::VerIterator &b)
+ {
+ // CmpVersion sorts ascending
+ int cmp = Cache_.VS().CmpVersion(a.VerStr(), b.VerStr());
+ if (cmp == 0)
+ {
+ const pkgCache::Package *A = &(*a.ParentPkg());
+ const pkgCache::Package *B = &(*b.ParentPkg());
+ // ScoreSort sorts descending
+ cmp = Fix_.ScoreSort(&B, &A);
+ }
+ //fprintf(stderr, "%s %s <=> %s %s = %d\n",
+ // a.ParentPkg().Name(), a.VerStr(),
+ // b.ParentPkg().Name(), b.VerStr(),
+ // cmp);
+ return cmp > 0;
+ }
+};
+
+static void __attribute__((unused))
+printVerList(const char *msg, const std::list<pkgCache::VerIterator> &list)
+{
+ std::list<pkgCache::VerIterator>::const_iterator I = list.begin();
+ for ( ; I != list.end(); ++I)
+ {
+ if (I == list.begin())
+ fprintf(stderr, "%s: ", msg);
+ else
+ fprintf(stderr, ", ");
+
+ const pkgCache::VerIterator &Ver = *I;
+ fprintf(stderr, "%s#%s", Ver.ParentPkg().Name(), Ver.VerStr());
+ }
+ fprintf(stderr, "\n");
+}
+
// CNC:2003-11-11
bool TryToChangeVer(pkgCache::PkgIterator &Pkg,pkgDepCache &Cache,
+ pkgProblemResolver &Fix,
int VerOp,const char *VerTag,bool IsRel)
{
// CNC:2003-11-05
pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release :
pkgVersionMatch::Version),VerOp);
- pkgCache::VerIterator Ver = Match.Find(Pkg);
-
- if (Ver.end() == true)
+ std::list<pkgCache::VerIterator> found = Match.FindAll(Pkg);
+ //printVerList("found", found);
+
+ if (found.size() == 0)
{
// CNC:2003-11-05
if (IsRel == true)
@@ -1547,16 +1594,67 @@ bool TryToChangeVer(pkgCache::PkgIterato
return _error->Error(_("Version %s'%s' for '%s' was not found"),
op2str(VerOp),VerTag,Pkg.Name());
}
+
+ if (found.size() > 1)
+ {
+ Fix.MakeScores();
+ bestVersionOrder order(Cache,Fix);
+ found.sort(order);
+ found.unique();
+ //printVerList("sorted", found);
+ }
+
+ pkgCache::VerIterator Ver = found.front();
+ int already = 0;
+
+ std::list<pkgCache::VerIterator>::const_iterator I = found.begin();
+ for ( ; I != found.end(); ++I)
+ {
+ const pkgCache::VerIterator &V = *I;
+ if (V.ParentPkg().CurrentVer() == V)
+ {
+ Ver = V;
+ already = 2;
+ break;
+ }
+ if (Cache[V.ParentPkg()].InstallVer == V)
+ {
+ Ver = V;
+ already = 1;
+ break;
+ }
+ }
- if (strcmp(VerTag,Ver.VerStr()) != 0)
+ if (strcmp(VerTag,Ver.VerStr()) != 0 || found.size() > 1)
{
// CNC:2003-11-11
+ const char *fmt;
if (IsRel == true)
- ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
- Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name());
+ {
+ if (already > 1)
+ fmt = _("Version %s#%s (%s) for %s%s%s is already installed\n");
+ else if (already)
+ fmt = _("Version %s#%s (%s) for %s%s%s is already selected for install\n");
+ else
+ fmt = _("Selected version %s#%s (%s) for %s%s%s\n");
+
+ ioprintf(c1out,fmt,
+ Ver.ParentPkg().Name(),Ver.VerStr(),Ver.RelStr().c_str(),
+ Pkg.Name(),op2str(VerOp),VerTag);
+ }
else
- ioprintf(c1out,_("Selected version %s for %s\n"),
- Ver.VerStr(),Pkg.Name());
+ {
+ if (already > 1)
+ fmt = _("Version %s#%s for %s%s%s is already installed\n");
+ else if (already)
+ fmt = _("Version %s#%s for %s%s%s is already selected for install\n");
+ else
+ fmt = _("Selected version %s#%s for %s%s%s\n");
+
+ ioprintf(c1out,fmt,
+ Ver.ParentPkg().Name(),Ver.VerStr(),
+ Pkg.Name(),op2str(VerOp),VerTag);
+ }
}
Cache.SetCandidateVersion(Ver);
@@ -2086,7 +2184,7 @@ bool DoInstall(CommandLine &CmdL)
if (VerTag != 0)
// CNC:2003-11-05
- if (TryToChangeVer(Pkg,Cache,VerOp,VerTag,VerIsRel) == false)
+ if (TryToChangeVer(Pkg,Cache,Fix,VerOp,VerTag,VerIsRel) == false)
return false;
Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
@@ -2101,7 +2199,7 @@ bool DoInstall(CommandLine &CmdL)
{
if (VerTag != 0)
// CNC:2003-11-05
- if (TryToChangeVer(Pkg,Cache,VerOp,VerTag,VerIsRel) == false)
+ if (TryToChangeVer(Pkg,Cache,Fix,VerOp,VerTag,VerIsRel) == false)
return false;
if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
return false;

View File

@ -164,11 +164,12 @@ bool pkgVersionMatch::MatchVer(const char *A,string B,bool Prefix)
// VersionMatch::Find - Locate the best match for the select type /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg)
std::list<pkgCache::VerIterator> pkgVersionMatch::FindAll(pkgCache::PkgIterator Pkg)
{
// CNC:2003-11-05
pkgVersioningSystem *VS = Pkg.Cache()->VS;
pkgCache::VerIterator Ver = Pkg.VersionList();
std::list<pkgCache::VerIterator> found;
for (; Ver.end() == false; Ver++)
{
@ -178,10 +179,10 @@ pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg)
if (VerPrefixMatch)
{
if (MatchVer(Ver.VerStr(),VerStr,VerPrefixMatch) == true)
return Ver;
found.push_back(Ver);
} else {
if (VS->CheckDep(Ver.VerStr(),VerOp,VerStr.c_str()) == true)
return Ver;
found.push_back(Ver);
}
continue;
@ -189,8 +190,11 @@ pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg)
for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; VF++)
if (FileMatch(VF.File()) == true)
return Ver;
found.push_back(Ver);
}
if (found.size() > 0)
goto done;
// CNC:2003-11-11 - Virtual package handling.
if (Type == Version)
@ -205,15 +209,28 @@ pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg)
if (VerPrefixMatch || (HasRelease && strchr(PrvVerStr, '-') == NULL))
{
if (MatchVer(PrvVerStr,VerStr,VerPrefixMatch) == true)
return Prv.OwnerVer();
found.push_back(Prv.OwnerVer());
} else {
if (VS->CheckDep(PrvVerStr,VerOp,VerStr.c_str()) == true)
return Prv.OwnerVer();
found.push_back(Prv.OwnerVer());
}
}
}
// This will be Ended by now.
done:
return found;
}
pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg)
{
std::list<pkgCache::VerIterator> found = FindAll(Pkg);
if (found.size() > 0)
return found.front();
// return "empty" iterator at its end
pkgCache::VerIterator Ver = Pkg.VersionList();
while (Ver.end() == false)
Ver++;
return Ver;
}
/*}}}*/

View File

@ -36,6 +36,7 @@
#endif
#include <string>
#include <list>
#include <apt-pkg/pkgcache.h>
using std::string;
@ -70,6 +71,7 @@ class pkgVersionMatch
// CNC:2003-11-05
pkgVersionMatch(string Data,MatchType Type,int Op=pkgCache::Dep::Equals);
std::list<pkgCache::VerIterator> FindAll(pkgCache::PkgIterator Pkg);
};
#endif

View File

@ -1531,17 +1531,64 @@ static const char *op2str(int op)
}
}
// best versions go first
class bestVersionOrder
{
private:
pkgDepCache &Cache_;
pkgProblemResolver &Fix_;
public:
bestVersionOrder(pkgDepCache &Cache, pkgProblemResolver &Fix)
: Cache_(Cache), Fix_(Fix) { }
bool operator() (const pkgCache::VerIterator &a, const pkgCache::VerIterator &b)
{
// CmpVersion sorts ascending
int cmp = Cache_.VS().CmpVersion(a.VerStr(), b.VerStr());
if (cmp == 0)
{
const pkgCache::Package *A = &(*a.ParentPkg());
const pkgCache::Package *B = &(*b.ParentPkg());
// ScoreSort sorts descending
cmp = Fix_.ScoreSort(&B, &A);
}
//fprintf(stderr, "%s %s <=> %s %s = %d\n",
// a.ParentPkg().Name(), a.VerStr(),
// b.ParentPkg().Name(), b.VerStr(),
// cmp);
return cmp > 0;
}
};
static void __attribute__((unused))
printVerList(const char *msg, const std::list<pkgCache::VerIterator> &list)
{
std::list<pkgCache::VerIterator>::const_iterator I = list.begin();
for ( ; I != list.end(); ++I)
{
if (I == list.begin())
fprintf(stderr, "%s: ", msg);
else
fprintf(stderr, ", ");
const pkgCache::VerIterator &Ver = *I;
fprintf(stderr, "%s#%s", Ver.ParentPkg().Name(), Ver.VerStr());
}
fprintf(stderr, "\n");
}
// CNC:2003-11-11
bool TryToChangeVer(pkgCache::PkgIterator &Pkg,pkgDepCache &Cache,
pkgProblemResolver &Fix,
int VerOp,const char *VerTag,bool IsRel)
{
// CNC:2003-11-05
pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release :
pkgVersionMatch::Version),VerOp);
pkgCache::VerIterator Ver = Match.Find(Pkg);
if (Ver.end() == true)
std::list<pkgCache::VerIterator> found = Match.FindAll(Pkg);
//printVerList("found", found);
if (found.size() == 0)
{
// CNC:2003-11-05
if (IsRel == true)
@ -1550,16 +1597,67 @@ bool TryToChangeVer(pkgCache::PkgIterator &Pkg,pkgDepCache &Cache,
return _error->Error(_("Version %s'%s' for '%s' was not found"),
op2str(VerOp),VerTag,Pkg.Name());
}
if (found.size() > 1)
{
Fix.MakeScores();
bestVersionOrder order(Cache,Fix);
found.sort(order);
found.unique();
//printVerList("sorted", found);
}
pkgCache::VerIterator Ver = found.front();
int already = 0;
std::list<pkgCache::VerIterator>::const_iterator I = found.begin();
for ( ; I != found.end(); ++I)
{
const pkgCache::VerIterator &V = *I;
if (V.ParentPkg().CurrentVer() == V)
{
Ver = V;
already = 2;
break;
}
if (Cache[V.ParentPkg()].InstallVer == V)
{
Ver = V;
already = 1;
break;
}
}
if (strcmp(VerTag,Ver.VerStr()) != 0)
if (strcmp(VerTag,Ver.VerStr()) != 0 || found.size() > 1)
{
// CNC:2003-11-11
const char *fmt;
if (IsRel == true)
ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name());
{
if (already > 1)
fmt = _("Version %s#%s (%s) for %s%s%s is already installed\n");
else if (already)
fmt = _("Version %s#%s (%s) for %s%s%s is already selected for install\n");
else
fmt = _("Selected version %s#%s (%s) for %s%s%s\n");
ioprintf(c1out,fmt,
Ver.ParentPkg().Name(),Ver.VerStr(),Ver.RelStr().c_str(),
Pkg.Name(),op2str(VerOp),VerTag);
}
else
ioprintf(c1out,_("Selected version %s for %s\n"),
Ver.VerStr(),Pkg.Name());
{
if (already > 1)
fmt = _("Version %s#%s for %s%s%s is already installed\n");
else if (already)
fmt = _("Version %s#%s for %s%s%s is already selected for install\n");
else
fmt = _("Selected version %s#%s for %s%s%s\n");
ioprintf(c1out,fmt,
Ver.ParentPkg().Name(),Ver.VerStr(),
Pkg.Name(),op2str(VerOp),VerTag);
}
}
Cache.SetCandidateVersion(Ver);
@ -2092,7 +2190,7 @@ bool DoInstall(CommandLine &CmdL)
if (VerTag != 0)
// CNC:2003-11-05
if (TryToChangeVer(Pkg,Cache,VerOp,VerTag,VerIsRel) == false)
if (TryToChangeVer(Pkg,Cache,Fix,VerOp,VerTag,VerIsRel) == false)
return false;
Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
@ -2107,7 +2205,7 @@ bool DoInstall(CommandLine &CmdL)
{
if (VerTag != 0)
// CNC:2003-11-05
if (TryToChangeVer(Pkg,Cache,VerOp,VerTag,VerIsRel) == false)
if (TryToChangeVer(Pkg,Cache,Fix,VerOp,VerTag,VerIsRel) == false)
return false;
if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
return false;