propagate a negative score point along breaks/conflicts
authorDavid Kalnischkies <david@kalnischkies.de>
Sat, 15 Feb 2014 12:38:39 +0000 (13:38 +0100)
committerDavid Kalnischkies <david@kalnischkies.de>
Thu, 13 Mar 2014 12:57:34 +0000 (13:57 +0100)
versioned -dev packages like db and boost have the problem of no
dependencies which would give them a competitive advantage against an
older incarnation of the -dev package, so they tend to be kept back
until the old version is removed from the archive, which, if the user
has older releases in its sources can take a long time (or never happens).

The newer version has a conflicts/breaks against the older one, but the
older one hasn't against the newer, so by giving via the conflicts the
older one a reduced score the newer one can win if there is no other
reason to keep it. If both have a conflict against each other the
scoring will cancel itself out, so no harm done.

This gives "action" a slightly bigger edge in breaks/conflicts cases
than before, but holding back isn't a really good solution anyway.

apt-pkg/algorithms.cc
test/integration/test-allow-scores-for-all-dependency-types [new file with mode: 0755]

index 0363ab3..db1ebd7 100644 (file)
@@ -394,8 +394,18 @@ void pkgProblemResolver::MakeScores()
    };
    int PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100);
    int PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1);
-   int PrioDepends = _config->FindI("pkgProblemResolver::Scores::Depends",1);
-   int PrioRecommends = _config->FindI("pkgProblemResolver::Scores::Recommends",1);
+   int DepMap[] = {
+      0,
+      _config->FindI("pkgProblemResolver::Scores::Depends",1),
+      _config->FindI("pkgProblemResolver::Scores::PreDepends",1),
+      _config->FindI("pkgProblemResolver::Scores::Suggests",0),
+      _config->FindI("pkgProblemResolver::Scores::Recommends",1),
+      _config->FindI("pkgProblemResolver::Scores::Conflicts",-1),
+      _config->FindI("pkgProblemResolver::Scores::Replaces",0),
+      _config->FindI("pkgProblemResolver::Scores::Obsoletes",0),
+      _config->FindI("pkgProblemResolver::Scores::Breaks",-1),
+      _config->FindI("pkgProblemResolver::Scores::Enhances",0)
+   };
    int AddProtected = _config->FindI("pkgProblemResolver::Scores::AddProtected",10000);
    int AddEssential = _config->FindI("pkgProblemResolver::Scores::AddEssential",5000);
 
@@ -408,8 +418,15 @@ void pkgProblemResolver::MakeScores()
          << "  Extra => " << PrioMap[pkgCache::State::Extra] << endl
          << "  Essentials => " << PrioEssentials << endl
          << "  InstalledAndNotObsolete => " << PrioInstalledAndNotObsolete << endl
-         << "  Depends => " << PrioDepends << endl
-         << "  Recommends => " << PrioRecommends << endl
+         << "  Pre-Depends => " << DepMap[pkgCache::Dep::PreDepends] << endl
+         << "  Depends => " << DepMap[pkgCache::Dep::Depends] << endl
+         << "  Recommends => " << DepMap[pkgCache::Dep::Recommends] << endl
+         << "  Suggests => " << DepMap[pkgCache::Dep::Suggests] << endl
+         << "  Conflicts => " << DepMap[pkgCache::Dep::Conflicts] << endl
+         << "  Breaks => " << DepMap[pkgCache::Dep::DpkgBreaks] << endl
+         << "  Replaces => " << DepMap[pkgCache::Dep::Replaces] << endl
+         << "  Obsoletes => " << DepMap[pkgCache::Dep::Obsoletes] << endl
+         << "  Enhances => " << DepMap[pkgCache::Dep::Enhances] << endl
          << "  AddProtected => " << AddProtected << endl
          << "  AddEssential => " << AddEssential << endl;
 
@@ -446,17 +463,11 @@ void pkgProblemResolver::MakeScores()
    {
       if (Cache[I].InstallVer == 0)
         continue;
-      
+
       for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false; ++D)
-      {
-        if (D->Type == pkgCache::Dep::Depends || 
-            D->Type == pkgCache::Dep::PreDepends)
-           Scores[D.TargetPkg()->ID] += PrioDepends;
-        else if (D->Type == pkgCache::Dep::Recommends)
-           Scores[D.TargetPkg()->ID] += PrioRecommends;
-      }
-   }   
-   
+        Scores[D.TargetPkg()->ID] += DepMap[D->Type];
+   }
+
    // Copy the scores to advoid additive looping
    SPtrArray<int> OldScores = new int[Size];
    memcpy(OldScores,Scores,sizeof(*Scores)*Size);
diff --git a/test/integration/test-allow-scores-for-all-dependency-types b/test/integration/test-allow-scores-for-all-dependency-types
new file mode 100755 (executable)
index 0000000..7e15a88
--- /dev/null
@@ -0,0 +1,47 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'amd64'
+
+insertinstalledpackage 'libdb-dev' 'amd64' '5.1.7' 'Depends: libdb5.1-dev'
+insertinstalledpackage 'libdb5.1-dev' 'amd64' '5.1.29-7'
+
+insertpackage 'unstable' 'libdb-dev' 'amd64' '5.3.0' 'Depends: libdb5.3-dev
+Conflicts: libdb5.1-dev'
+insertpackage 'unstable' 'libdb5.1-dev' 'amd64' '5.1.29-7'
+insertpackage 'unstable' 'libdb5.3-dev' 'amd64' '5.3.28-3' 'Conflicts: libdb5.1-dev'
+
+insertpackage 'unstable' 'foo' 'amd64' '1'
+insertpackage 'unstable' 'bar' 'amd64' '1'
+insertpackage 'unstable' 'foo' 'amd64' '2' 'Conflicts: bar'
+insertpackage 'unstable' 'bar' 'amd64' '2' 'Conflicts: foo'
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages will be REMOVED:
+  libdb5.1-dev
+The following NEW packages will be installed:
+  libdb5.3-dev
+The following packages will be upgraded:
+  libdb-dev
+1 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
+Remv libdb5.1-dev [5.1.29-7] [libdb-dev:amd64 ]
+Inst libdb-dev [5.1.7] (5.3.0 unstable [amd64]) []
+Inst libdb5.3-dev (5.3.28-3 unstable [amd64])
+Conf libdb5.3-dev (5.3.28-3 unstable [amd64])
+Conf libdb-dev (5.3.0 unstable [amd64])' aptget dist-upgrade -s
+
+rm rootdir/var/lib/dpkg/status
+insertinstalledpackage 'foo' 'amd64' '1'
+insertinstalledpackage 'bar' 'amd64' '1'
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages have been kept back:
+  bar foo
+0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.' aptget dist-upgrade -s