summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/algorithms.cc49
-rwxr-xr-xtest/integration/test-resolver-provider-exchange107
2 files changed, 147 insertions, 9 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index cba772d41..cd09a6944 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -517,18 +517,37 @@ void pkgProblemResolver::MakeScores()
Score += PrioInstalledAndNotObsolete;
// propagate score points along dependencies
- for (pkgCache::DepIterator D = InstVer.DependsList(); D.end() == false; ++D)
+ for (pkgCache::DepIterator D = InstVer.DependsList(); not D.end(); ++D)
{
if (DepMap[D->Type] == 0)
continue;
pkgCache::PkgIterator const T = D.TargetPkg();
- if (D->Version != 0)
+ if (not D.IsIgnorable(T))
{
- pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache);
- if (IV.end() == true || D.IsSatisfied(IV) == false)
+ if (D->Version != 0)
+ {
+ pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache);
+ if (IV.end() || not D.IsSatisfied(IV))
+ continue;
+ }
+ Scores[T->ID] += DepMap[D->Type];
+ }
+
+ std::vector<map_id_t> providers;
+ for (auto Prv = T.ProvidesList(); not Prv.end(); ++Prv)
+ {
+ if (D.IsIgnorable(Prv))
+ continue;
+ auto const PV = Prv.OwnerVer();
+ auto const PP = PV.ParentPkg();
+ if (PV != Cache[PP].InstVerIter(Cache) || not D.IsSatisfied(Prv))
continue;
+ providers.push_back(PP->ID);
}
- Scores[T->ID] += DepMap[D->Type];
+ std::sort(providers.begin(), providers.end());
+ providers.erase(std::unique(providers.begin(), providers.end()), providers.end());
+ for (auto const prv : providers)
+ Scores[prv] += DepMap[D->Type];
}
}
@@ -564,13 +583,25 @@ void pkgProblemResolver::MakeScores()
provide important packages extremely important */
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
{
- for (pkgCache::PrvIterator P = I.ProvidesList(); P.end() == false; ++P)
+ auto const transfer = abs(Scores[I->ID] - OldScores[I->ID]);
+ if (transfer == 0)
+ continue;
+
+ std::vector<map_id_t> providers;
+ for (auto Prv = I.ProvidesList(); not Prv.end(); ++Prv)
{
- // Only do it once per package
- if ((pkgCache::Version *)P.OwnerVer() != Cache[P.OwnerPkg()].InstallVer)
+ if (Prv.IsMultiArchImplicit())
+ continue;
+ auto const PV = Prv.OwnerVer();
+ auto const PP = PV.ParentPkg();
+ if (PV != Cache[PP].InstVerIter(Cache))
continue;
- Scores[P.OwnerPkg()->ID] += abs(Scores[I->ID] - OldScores[I->ID]);
+ providers.push_back(PP->ID);
}
+ std::sort(providers.begin(), providers.end());
+ providers.erase(std::unique(providers.begin(), providers.end()), providers.end());
+ for (auto const prv : providers)
+ Scores[prv] += transfer;
}
/* Protected things are pushed really high up. This number should put them
diff --git a/test/integration/test-resolver-provider-exchange b/test/integration/test-resolver-provider-exchange
new file mode 100755
index 000000000..3f5310fa6
--- /dev/null
+++ b/test/integration/test-resolver-provider-exchange
@@ -0,0 +1,107 @@
+#!/bin/sh
+set -e
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+setupenvironment
+configarchitecture 'amd64'
+
+insertinstalledpackage 'fuse' 'all' '2'
+insertpackage 'unstable' 'fuse3' 'all' '3' 'Conflicts: fuse
+Provides: fuse'
+
+insertpackage 'unstable' 'foobar-d' 'all' '1' 'Depends: fuse'
+insertpackage 'unstable' 'foobar-d2' 'all' '1' 'Depends: fuse
+Conflicts: fuse3'
+insertpackage 'unstable' 'foobar-d3' 'all' '1' 'Depends: fuse3'
+insertpackage 'unstable' 'foobar-r' 'all' '1' 'Recommends: fuse'
+insertpackage 'unstable' 'foobar-r2' 'all' '1' 'Recommends: fuse
+Conflicts: fuse3'
+insertpackage 'unstable' 'foobar-r3' 'all' '1' 'Recommends: fuse3'
+
+setupaptarchive
+
+installfoobars() {
+ testsuccessequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ foobar-d
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst foobar-d (1 unstable [all])
+Conf foobar-d (1 unstable [all])' apt install -s foobar-d
+ testsuccessequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ foobar-d2
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst foobar-d2 (1 unstable [all])
+Conf foobar-d2 (1 unstable [all])' apt install -s foobar-d2
+ testsuccessequal "Reading package lists...
+Building dependency tree...
+The following additional packages will be installed:
+ fuse3
+The following packages will be REMOVED:
+ fuse
+The following NEW packages will be installed:
+ foobar-d3 fuse3
+0 upgraded, 2 newly installed, 1 to remove and 0 not upgraded.
+Remv fuse [2]$1
+Inst fuse3 (3 unstable [all])
+Inst foobar-d3 (1 unstable [all])
+Conf fuse3 (3 unstable [all])
+Conf foobar-d3 (1 unstable [all])" apt install -s foobar-d3
+
+ testsuccessequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ foobar-r
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst foobar-r (1 unstable [all])
+Conf foobar-r (1 unstable [all])' apt install -s foobar-r
+ testsuccessequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ foobar-r2
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst foobar-r2 (1 unstable [all])
+Conf foobar-r2 (1 unstable [all])' apt install -s foobar-r2
+ if [ -z "$1" ]; then
+ testsuccessequal "Reading package lists...
+Building dependency tree...
+The following additional packages will be installed:
+ fuse3
+The following packages will be REMOVED:
+ fuse
+The following NEW packages will be installed:
+ foobar-r3 fuse3
+0 upgraded, 2 newly installed, 1 to remove and 0 not upgraded.
+Remv fuse [2]$1
+Inst foobar-r3 (1 unstable [all])
+Inst fuse3 (3 unstable [all])
+Conf foobar-r3 (1 unstable [all])
+Conf fuse3 (3 unstable [all])" apt install -s foobar-r3
+ else
+ testsuccessequal "Reading package lists...
+Building dependency tree...
+The following additional packages will be installed:
+ fuse3
+The following packages will be REMOVED:
+ fuse
+The following NEW packages will be installed:
+ foobar-r3 fuse3
+0 upgraded, 2 newly installed, 1 to remove and 0 not upgraded.
+Remv fuse [2]$1
+Inst fuse3 (3 unstable [all])
+Inst foobar-r3 (1 unstable [all])
+Conf fuse3 (3 unstable [all])
+Conf foobar-r3 (1 unstable [all])" apt install -s foobar-r3
+ fi
+}
+msgmsg 'fuse has no installed dependers'
+installfoobars
+
+for i in $(seq 0 10); do
+ insertinstalledpackage "stuff$i" 'all' '1' 'Depends: fuse'
+done
+msgmsg 'fuse has many dependers installed'
+installfoobars ' [stuff10:amd64 stuff0:amd64 stuff1:amd64 stuff2:amd64 stuff3:amd64 stuff4:amd64 stuff5:amd64 stuff6:amd64 stuff7:amd64 stuff8:amd64 stuff9:amd64 ]'