Fix package selection logic so that it always properly finds the highest
authorZac Medico <zmedico@gentoo.org>
Thu, 3 Apr 2008 22:34:46 +0000 (22:34 -0000)
committerZac Medico <zmedico@gentoo.org>
Thu, 3 Apr 2008 22:34:46 +0000 (22:34 -0000)
available version in a new slot even though the graph already contains
a matching version in a lower slot.

svn path=/main/trunk/; revision=9693

pym/_emerge/__init__.py

index 80ddca31d8b5050d03fff798aacc299f17c1f9e9..8b6ee4add5dbd61f1410ca00e288e4be50e458c1 100644 (file)
@@ -1207,6 +1207,24 @@ class Package(object):
                        status = "nomerge"
                self._digraph_node = (self.type_name, self.root, self.cpv, status)
 
+       def __lt__(self, other):
+               other_split = portage.catpkgsplit(other.cpv)
+               self_split = portage.catpkgsplit(self.cpv)
+               if other_split[:2] != self_split[:2]:
+                       return False
+               if portage.pkgcmp(self_split[1:], other_split[1:]) < 0:
+                       return True
+               return False
+
+       def __gt__(self, other):
+               other_split = portage.catpkgsplit(other.cpv)
+               self_split = portage.catpkgsplit(self.cpv)
+               if other_split[:2] != self_split[:2]:
+                       return False
+               if portage.pkgcmp(self_split[1:], other_split[1:]) > 0:
+                       return True
+               return False
+
        def __eq__(self, other):
                return self._digraph_node == other
        def __ne__(self, other):
@@ -2562,6 +2580,8 @@ class depgraph(object):
                portdb = self.roots[root].trees["porttree"].dbapi
                # List of acceptable packages, ordered by type preference.
                matched_packages = []
+               highest_version = None
+               atom_cp = portage.dep_getkey(atom)
                existing_node = None
                myeb = None
                usepkgonly = "--usepkgonly" in self.myopts
@@ -2626,13 +2646,18 @@ class depgraph(object):
                                                        if not installed:
                                                                # masked by corruption
                                                                continue
+                                       pkg = Package(built=built, cpv=cpv, installed=installed,
+                                               metadata=metadata, type_name=pkg_type)
                                        if not installed:
                                                if myarg:
                                                        found_available_arg = True
-                                               if not visible(pkgsettings, Package(built=built,
-                                                       cpv=cpv, installed=installed, metadata=metadata,
-                                                       type_name=pkg_type)):
+                                               if not visible(pkgsettings, pkg):
                                                        continue
+                                       if pkg.cp == atom_cp:
+                                               if highest_version is None:
+                                                       highest_version = pkg
+                                               elif pkg > highest_version:
+                                                       highest_version = pkg
                                        # At this point, we've found the highest visible
                                        # match from the current repo. Any lower versions
                                        # from this repo are ignored, so this so the loop
@@ -2647,8 +2672,17 @@ class depgraph(object):
                                                cpv_slot = "%s:%s" % \
                                                        (e_pkg.cpv, e_pkg.metadata["SLOT"])
                                                if portage.dep.match_from_list(atom, [cpv_slot]):
-                                                       matched_packages.append(e_pkg)
-                                                       existing_node = e_pkg
+                                                       if highest_version and \
+                                                               e_pkg.cp == atom_cp and \
+                                                               e_pkg < highest_version and \
+                                                               e_pkg.slot_atom != highest_version.slot_atom:
+                                                               # There is a higher version available in a
+                                                               # different slot, so this existing node is
+                                                               # irrelevant.
+                                                               pass
+                                                       else:
+                                                               matched_packages.append(e_pkg)
+                                                               existing_node = e_pkg
                                                break
                                        # Compare built package to current config and
                                        # reject the built package if necessary.