Merged from trunk -r15780:15790
authorFabian Groffen <grobian@gentoo.org>
Tue, 9 Mar 2010 11:29:06 +0000 (11:29 -0000)
committerFabian Groffen <grobian@gentoo.org>
Tue, 9 Mar 2010 11:29:06 +0000 (11:29 -0000)
   | 15783   | Bug #303567 - Create implicit dependencies on libc, in order |
   | zmedico | to ensure that libc is installed as early as possible.       |

   | 15784   | Fix typo in parenthesis from previous commit.                |
   | zmedico |                                                              |

   | 15787   | Add support for displaying profile listed in                 |
   | zmedico | make.profile/parent when make.profile is not a symlink. The  |
   |         | first parent with a path inside $PORTDIR is displayed.       |

   | 15789   | If _implicit_libc_deps() finds both a new-style virtual and  |
   | zmedico | an old-style PROVIDE virtual, use the new-style virtual.     |

   | 15790   | Add --debug output for the scheduler digraph.                |
   | zmedico |                                                              |

svn path=/main/branches/prefix/; revision=15799

pym/_emerge/Scheduler.py
pym/_emerge/actions.py

index a97adc04131a9f8ec863b8843d78a2ce1a8f6866..c35c2eabac6c04f4ccd6f2597cf523ea3a9b35e0 100644 (file)
@@ -18,6 +18,7 @@ from portage import _encodings
 from portage import _unicode_decode
 from portage import _unicode_encode
 from portage.cache.mappings import slot_dict_class
+from portage.const import LIBC_PACKAGE_ATOM
 from portage.elog.messages import eerror
 from portage.output import colorize, create_color_func, darkgreen, red
 bad = create_color_func("BAD")
@@ -351,6 +352,11 @@ class Scheduler(PollScheduler):
                self._find_system_deps()
                self._prune_digraph()
                self._prevent_builddir_collisions()
+               self._implicit_libc_deps()
+               if '--debug' in self.myopts:
+                       writemsg("\nscheduler digraph:\n\n", noiselevel=-1)
+                       self._digraph.debug_print()
+                       writemsg("\n", noiselevel=-1)
 
        def _find_system_deps(self):
                """
@@ -412,6 +418,56 @@ class Scheduler(PollScheduler):
                                        priority=DepPriority(buildtime=True))
                        cpv_map[pkg.cpv].append(pkg)
 
+       def _implicit_libc_deps(self):
+               """
+               Create implicit dependencies on libc, in order to ensure that libc
+               is installed as early as possible (see bug #303567). If the merge
+               list contains both a new-style virtual and an old-style PROVIDE
+               virtual, the new-style virtual is used.
+               """
+               libc_set = InternalPackageSet([LIBC_PACKAGE_ATOM])
+               norm_libc_pkgs = {}
+               virt_libc_pkgs = {}
+               for pkg in self._mergelist:
+                       if not isinstance(pkg, Package):
+                               # a satisfied blocker
+                               continue
+                       if pkg.installed:
+                               continue
+                       if pkg.operation == 'merge':
+                               if libc_set.findAtomForPackage(pkg):
+                                       if pkg.category == 'virtual':
+                                               d = virt_libc_pkgs
+                                       else:
+                                               d = norm_libc_pkgs
+                                       if pkg.root in d:
+                                               raise AssertionError(
+                                                       "found 2 libc matches: %s and %s" % \
+                                                       (d[pkg.root], pkg))
+                                       d[pkg.root] = pkg
+
+               # Prefer new-style virtuals over old-style PROVIDE virtuals.
+               libc_pkg_map = norm_libc_pkgs.copy()
+               libc_pkg_map.update(virt_libc_pkgs)
+               libc_pkgs = set(libc_pkg_map.values())
+               earlier_libc_pkgs = set()
+
+               for pkg in self._mergelist:
+                       if not isinstance(pkg, Package):
+                               # a satisfied blocker
+                               continue
+                       if pkg.installed:
+                               continue
+                       if pkg.operation == 'merge':
+                               if pkg in libc_pkgs:
+                                       earlier_libc_pkgs.add(pkg)
+                               else:
+                                       my_libc = libc_pkg_map.get(pkg.root)
+                                       if my_libc is not None and \
+                                               my_libc in earlier_libc_pkgs:
+                                               self._digraph.add(my_libc, pkg,
+                                                       priority=DepPriority(buildtime=True))
+
        class _pkg_failure(portage.exception.PortageException):
                """
                An instance of this class is raised by unmerge() when
index 372c5017fc38da48f9f1cbf8b44e147619f47794..53557fa82cd6f8055cf72b0aef6ca17dfe6d7082 100644 (file)
@@ -2477,19 +2477,38 @@ def display_missing_pkg_set(root_config, set_name):
        writemsg_level("".join("%s\n" % l for l in msg),
                level=logging.ERROR, noiselevel=-1)
 
+def relative_profile_path(portdir, abs_profile):
+       realpath = os.path.realpath(abs_profile)
+       basepath   = os.path.realpath(os.path.join(portdir, "profiles"))
+       if realpath.startswith(basepath):
+               profilever = realpath[1 + len(basepath):]
+       else:
+               profilever = None
+       return profilever
+
 def getportageversion(portdir, target_root, profile, chost, vardb):
-       profilever = "unavailable"
+       profilever = None
        if profile:
-               realpath = os.path.realpath(profile)
-               basepath   = os.path.realpath(os.path.join(portdir, "profiles"))
-               if realpath.startswith(basepath):
-                       profilever = realpath[1 + len(basepath):]
-               else:
+               profilever = relative_profile_path(portdir, profile)
+               if profilever is None:
                        try:
-                               profilever = "!" + os.readlink(profile)
-                       except (OSError):
+                               for parent in portage.grabfile(
+                                       os.path.join(profile, 'parent')):
+                                       profilever = relative_profile_path(portdir,
+                                               os.path.join(profile, parent))
+                                       if profilever is not None:
+                                               break
+                       except portage.exception.PortageException:
                                pass
-               del realpath, basepath
+
+                       if profilever is None:
+                               try:
+                                       profilever = "!" + os.readlink(profile)
+                               except (OSError):
+                                       pass
+
+       if profilever is None:
+               profilever = "unavailable"
 
        libcver=[]
        libclist  = vardb.match("virtual/libc")