Merged from trunk -r11724:11733
authorFabian Groffen <grobian@gentoo.org>
Tue, 28 Oct 2008 19:09:53 +0000 (19:09 -0000)
committerFabian Groffen <grobian@gentoo.org>
Tue, 28 Oct 2008 19:09:53 +0000 (19:09 -0000)
   | 11725   | When creating the temporary $DISTDIR, do not try to set the  |
   | zmedico | uid since it will fail when not running as root.             |

   | 11726   | Enable bashrc even when $EBUILD_PHASE is unset, so it's      |
   | zmedico | possible to override things like INSTALL_MASK.               |

   | 11727   | In fetch(), avoid the "Adjusting permissions recursively"    |
   | zmedico | message in cases when the directory has just been created    |
   |         | and therefore it must be empty.                              |

   | 11728   | Return early from fetch() if no uris are given.              |
   | zmedico |                                                              |

   | 11729   | Pass $ROOT into portage.util.getlibpaths().                  |
   | zmedico |                                                              |

   | 11730   | Pass $ROOT into the LinkageMap._ObjectKey constructor since  |
   | zmedico | it's needed for os.stat() and realpath() calls.              |

   | 11731   | Fix incorrect $ROOT handling inside dblink._preserve_libs(). |
   | zmedico |                                                              |

   | 11732   | Make SetConfig.getSetAtoms() raise a PackageSetNotFound      |
   | zmedico | exception when necessary and add handling code in emerge.    |
   |         | This solves an unhandled KeyError that was raise when a      |
   |         | nested set did not exist. Thanks to ABCD for reporting.      |

   | 11733   | Fix some incorrect $ROOT handling inside LinkageMap.         |
   | zmedico |                                                              |

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

bin/ebuild.sh
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/dbapi/vartree.py
pym/portage/sets/__init__.py
pym/portage/util.py

index 4f6cefebe3b9e605faf8d51f25955af805536e40..6a935f829e8eac2eb2e920b9ef948f22f84fc52a 100755 (executable)
@@ -1535,10 +1535,9 @@ _ebuild_phase_funcs() {
 #    function for the current phase.
 #
 source_all_bashrcs() {
-       [ -n "$EBUILD_PHASE" ] || return
        local x
 
-       if [[ -n ${EAPI/prefix/} ]] ; then
+       if [[ -n $EBUILD_PHASE && -n ${EAPI/prefix/} ]] ; then
                # PREFIX HACK: just remove "prefix" from EAPI here, this file
                # currently assumes EAPI to contain a single token, and "prefix"
                # is ortogonal to all supported EAPIs here.
index 82e08cef48d0604caa03a529b0f06d22603959b2..d567e2b1ecca441ba22d186e84a94070d8b067c4 100644 (file)
@@ -13788,15 +13788,22 @@ def expand_set_arguments(myfiles, myaction, root_config):
                                        display_missing_pkg_set(root_config, s)
                                        return (None, 1)
                                setconfig.active.append(s)
+                               try:
+                                       set_atoms = setconfig.getSetAtoms(s)
+                               except portage.exception.PackageSetNotFound, e:
+                                       writemsg_level(("emerge: the given set '%s' " + \
+                                               "contains a non-existent set named '%s'.\n") % \
+                                               (s, e), level=logging.ERROR, noiselevel=-1)
+                                       return (None, 1)
                                if myaction in unmerge_actions and \
                                                not sets[s].supportsOperation("unmerge"):
                                        sys.stderr.write("emerge: the given set '%s' does " % s + \
                                                "not support unmerge operations\n")
                                        retval = 1
-                               elif not setconfig.getSetAtoms(s):
+                               elif not set_atoms:
                                        print "emerge: '%s' is an empty set" % s
                                elif myaction not in do_not_expand:
-                                       newargs.extend(setconfig.getSetAtoms(s))
+                                       newargs.extend(set_atoms)
                                else:
                                        newargs.append(SETPREFIX+s)
                                for e in sets[s].errors:
index 575a59511804e425c49418c8dc0b5483a51cbdfd..eed7321fdbb76cd5581642cafca7b391b099b309 100644 (file)
@@ -3359,6 +3359,9 @@ _size_suffix_map = {
 def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",use_locks=1, try_mirrors=1):
        "fetch files.  Will use digest file if available."
 
+       if not myuris:
+               return 1
+
        features = mysettings.features
        restrict = mysettings.get("PORTAGE_RESTRICT","").split()
 
@@ -3603,7 +3606,12 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
                                write_test_file = os.path.join(
                                        mydir, ".__portage_test_write__")
 
-                               if os.path.isdir(mydir):
+                               try:
+                                       st = os.stat(mydir)
+                               except OSError:
+                                       st = None
+
+                               if st is not None and stat.S_ISDIR(st.st_mode):
                                        if not (userfetch or userpriv):
                                                continue
                                        if _userpriv_test_write_file(mysettings, write_test_file):
@@ -3611,6 +3619,10 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
 
                                _userpriv_test_write_file_cache.pop(write_test_file, None)
                                if portage.util.ensure_dirs(mydir, gid=dir_gid, mode=dirmode, mask=modemask):
+                                       if st is None:
+                                               # The directory has just been created
+                                               # and therefore it must be empty.
+                                               continue
                                        writemsg("Adjusting permissions recursively: '%s'\n" % mydir,
                                                noiselevel=-1)
                                        def onerror(e):
@@ -5704,7 +5716,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                        mysettings["PORTAGE_ACTUAL_DISTDIR"] = orig_distdir
                        edpath = mysettings["DISTDIR"] = \
                                os.path.join(mysettings["PORTAGE_BUILDDIR"], "distdir")
-                       portage.util.ensure_dirs(edpath, uid=portage_uid, mode=0755)
+                       portage.util.ensure_dirs(edpath, gid=portage_gid, mode=0755)
 
                        # Remove any unexpected files or directories.
                        for x in os.listdir(edpath):
index 996fa517b8bc1d112b41b6abe426d26dec0c9ca2..77ac7ebaffe3484362bc79a7574df14da420e308 100644 (file)
@@ -144,9 +144,10 @@ class LinkageMap(object):
 
        def __init__(self, vardbapi):
                self._dbapi = vardbapi
+               self._root = self._dbapi.root
                self._libs = {}
                self._obj_properties = {}
-               self._defpath = set(getlibpaths())
+               self._defpath = set(getlibpaths(self._root))
                self._obj_key_cache = {}
 
        class _ObjectKey(object):
@@ -155,7 +156,7 @@ class LinkageMap(object):
 
                __slots__ = ("__weakref__", "_key")
 
-               def __init__(self, object):
+               def __init__(self, object, root):
                        """
                        This takes a path to an object.
 
@@ -163,7 +164,7 @@ class LinkageMap(object):
                        @type object: string (example: '/usr/bin/bar')
 
                        """
-                       self._key = self._generate_object_key(object)
+                       self._key = self._generate_object_key(object, root)
 
                def __hash__(self):
                        return hash(self._key)
@@ -171,7 +172,7 @@ class LinkageMap(object):
                def __eq__(self, other):
                        return self._key == other._key
 
-               def _generate_object_key(self, object):
+               def _generate_object_key(self, object, root):
                        """
                        Generate object key for a given object.
 
@@ -185,12 +186,13 @@ class LinkageMap(object):
                                2. realpath of object if object does not exist.
 
                        """
+                       abs_path = os.path.join(root, object.lstrip(os.path.sep))
                        try:
-                               object_stat = os.stat(object)
+                               object_stat = os.stat(abs_path)
                        except OSError:
                                # Use the realpath as the key if the file does not exists on the
                                # filesystem.
-                               return os.path.realpath(object)
+                               return os.path.realpath(abs_path)
                        # Return a tuple of the device and inode.
                        return (object_stat.st_dev, object_stat.st_ino)
 
@@ -207,6 +209,7 @@ class LinkageMap(object):
                        return isinstance(self._key, tuple)
 
        def rebuild(self, include_file=None):
+               root = self._root
                libs = {}
                obj_key_cache = {}
                obj_properties = {}
@@ -239,9 +242,10 @@ class LinkageMap(object):
                                continue
                        arch = fields[0]
                        obj = fields[1]
-                       obj_key = self._ObjectKey(obj)
+                       obj_key = self._ObjectKey(obj, root)
                        soname = fields[2]
-                       path = set([normalize_path(x)
+                       path = set([
+                               normalize_path(os.path.join(self._root, x.lstrip(os.path.sep)))
                                for x in filter(None, fields[3].replace(
                                "${ORIGIN}", os.path.dirname(obj)).replace(
                                "$ORIGIN", os.path.dirname(obj)).split(":"))])
@@ -313,7 +317,7 @@ class LinkageMap(object):
                                        if obj in self._obj_key_cache:
                                                obj_key = self._obj_key_cache.get(obj)
                                        else:
-                                               obj_key = self._ObjectKey(obj)
+                                               obj_key = self._ObjectKey(obj, self._root)
                                        # Check that the library exists on the filesystem.
                                        if obj_key.file_exists():
                                                # Get the arch and soname from LinkageMap._obj_properties if
@@ -427,7 +431,7 @@ class LinkageMap(object):
 
                """
                basename = os.path.basename(obj)
-               obj_key = self._ObjectKey(obj)
+               obj_key = self._ObjectKey(obj, self._root)
                if obj_key not in self._obj_properties:
                        raise KeyError("%s (%s) not in object list" % (obj_key, obj))
                soname = self._obj_properties[obj_key][3]
@@ -501,7 +505,7 @@ class LinkageMap(object):
                else:
                        obj_key = self._obj_key_cache.get(obj)
                        if obj_key not in self._obj_properties:
-                               obj_key = self._ObjectKey(obj)
+                               obj_key = self._ObjectKey(obj, self._root)
                                if obj_key not in self._obj_properties:
                                        raise KeyError("%s (%s) not in object list" % (obj_key, obj))
 
@@ -516,7 +520,8 @@ class LinkageMap(object):
                        for provider_key in self._libs[soname][arch]["providers"]:
                                providers = self._obj_properties[provider_key][4]
                                for provider in providers:
-                                       if os.path.dirname(provider) in path:
+                                       if os.path.join(self._root,
+                                               os.path.dirname(provider).lstrip(os.path.sep)) in path:
                                                rValue[soname].add(provider)
                return rValue
 
@@ -555,7 +560,7 @@ class LinkageMap(object):
                        objs = set([obj])
                        obj_key = self._obj_key_cache.get(obj)
                        if obj_key not in self._obj_properties:
-                               obj_key = self._ObjectKey(obj)
+                               obj_key = self._ObjectKey(obj, self._root)
                                if obj_key not in self._obj_properties:
                                        raise KeyError("%s (%s) not in object list" % (obj_key, obj))
 
@@ -568,8 +573,8 @@ class LinkageMap(object):
                # have any consumers.
                if not isinstance(obj, self._ObjectKey):
                        soname = self._obj_properties[obj_key][3]
-                       obj_dir = os.path.dirname(obj)
-                       master_link = os.path.join(obj_dir, soname)
+                       master_link = os.path.join(self._root,
+                               os.path.dirname(obj).lstrip(os.path.sep), soname)
                        try:
                                master_st = os.stat(master_link)
                                obj_st = os.stat(obj)
@@ -598,6 +603,7 @@ class LinkageMapMachO(object):
 
        def __init__(self, vardbapi):
                self._dbapi = vardbapi
+               self._root = self._dbapi.root
                self._libs = {}
                self._obj_properties = {}
                self._obj_key_cache = {}
@@ -608,7 +614,7 @@ class LinkageMapMachO(object):
 
                __slots__ = ("__weakref__", "_key")
 
-               def __init__(self, object):
+               def __init__(self, object, root):
                        """
                        This takes a path to an object.
 
@@ -616,7 +622,7 @@ class LinkageMapMachO(object):
                        @type object: string (example: '/usr/bin/bar')
 
                        """
-                       self._key = self._generate_object_key(object)
+                       self._key = self._generate_object_key(object, root)
 
                def __hash__(self):
                        return hash(self._key)
@@ -624,7 +630,7 @@ class LinkageMapMachO(object):
                def __eq__(self, other):
                        return self._key == other._key
 
-               def _generate_object_key(self, object):
+               def _generate_object_key(self, object, root):
                        """
                        Generate object key for a given object.
 
@@ -638,12 +644,13 @@ class LinkageMapMachO(object):
                                2. realpath of object if object does not exist.
 
                        """
+                       abs_path = os.path.join(root, object.lstrip(os.path.sep))
                        try:
-                               object_stat = os.stat(object)
+                               object_stat = os.stat(abs_path)
                        except OSError:
                                # Use the realpath as the key if the file does not exists on the
                                # filesystem.
-                               return os.path.realpath(object)
+                               return os.path.realpath(abs_path)
                        # Return a tuple of the device and inode.
                        return (object_stat.st_dev, object_stat.st_ino)
 
@@ -660,6 +667,7 @@ class LinkageMapMachO(object):
                        return isinstance(self._key, tuple)
 
        def rebuild(self, include_file=None):
+               root = self._root
                libs = {}
                obj_key_cache = {}
                obj_properties = {}
@@ -695,7 +703,7 @@ class LinkageMapMachO(object):
                        # the install_name of the library in the object.
                        arch = fields[0]
                        obj = fields[1]
-                       obj_key = self._ObjectKey(obj)
+                       obj_key = self._ObjectKey(obj, root)
                        install_name = os.path.normpath(fields[2])
                        needed = filter(None, fields[3].split(","))
 
@@ -772,7 +780,7 @@ class LinkageMapMachO(object):
                                        if obj in self._obj_key_cache:
                                                obj_key = self._obj_key_cache.get(obj)
                                        else:
-                                               obj_key = self._ObjectKey(obj)
+                                               obj_key = self._ObjectKey(obj, self._root)
                                        # Check that the library exists on the filesystem.
                                        if obj_key.file_exists():
                                                # Get the install_name from LinkageMapMachO._obj_properties if
@@ -870,7 +878,7 @@ class LinkageMapMachO(object):
 
                """
                basename = os.path.basename(obj)
-               obj_key = self._ObjectKey(obj)
+               obj_key = self._ObjectKey(obj, self._root)
                if obj_key not in self._obj_properties:
                        raise KeyError("%s (%s) not in object list" % (obj_key, obj))
                install_name = self._obj_properties[obj_key][2]
@@ -944,7 +952,7 @@ class LinkageMapMachO(object):
                else:
                        obj_key = self._obj_key_cache.get(obj)
                        if obj_key not in self._obj_properties:
-                               obj_key = self._ObjectKey(obj)
+                               obj_key = self._ObjectKey(obj, self._root)
                                if obj_key not in self._obj_properties:
                                        raise KeyError("%s (%s) not in object list" % (obj_key, obj))
 
@@ -958,7 +966,8 @@ class LinkageMapMachO(object):
                        for provider_key in self._libs[install_name][arch]["providers"]:
                                providers = self._obj_properties[provider_key][3]
                                for provider in providers:
-                                       if os.path.exists(provider):
+                                       if os.path.exists(os.path.join(self._root,
+                                               provider.lstrip(os.path.sep))):
                                                rValue[install_name].add(provider)
                return rValue
 
@@ -997,7 +1006,7 @@ class LinkageMapMachO(object):
                        objs = set([obj])
                        obj_key = self._obj_key_cache.get(obj)
                        if obj_key not in self._obj_properties:
-                               obj_key = self._ObjectKey(obj)
+                               obj_key = self._ObjectKey(obj, self._root)
                                if obj_key not in self._obj_properties:
                                        raise KeyError("%s (%s) not in object list" % (obj_key, obj))
 
@@ -1006,7 +1015,8 @@ class LinkageMapMachO(object):
                # other version, this lib will be shadowed and won't
                # have any consumers.
                if not isinstance(obj, self._ObjectKey):
-                       master_link = self._obj_properties[obj_key][2]
+                       master_link = os.path.join(self._root,
+                                       self._obj_properties[obj_key][2].lstrip(os.path.sep))
                        try:
                                master_st = os.stat(master_link)
                                obj_st = os.stat(obj)
@@ -2863,13 +2873,30 @@ class dblink(object):
                old_libs = old_contents.intersection(liblist)
 
                # get list of libraries from new package instance
-               mylibs = set([os.path.join(os.sep, x) for x in mycontents]).intersection(liblist)
+               mycontents = set(os.path.join(os.path.sep, x) for x in mycontents)
+               mylibs = mycontents.intersection(liblist)
                
                # check which libs are present in the old, but not the new package instance
                candidates = old_libs.difference(mylibs)
-               
+               candidates_inodes = set()
+               for x in candidates:
+                       x_destroot = os.path.join(destroot, x.lstrip(os.path.sep))
+                       try:
+                               st = os.stat(x_destroot)
+                       except OSError:
+                               continue
+                       candidates_inodes.add((st.st_dev, st.st_ino))
+
                for x in old_contents:
-                       if os.path.islink(x) and os.path.realpath(x) in candidates and x not in mycontents:
+                       x_destroot = os.path.join(destroot, x.lstrip(os.path.sep))
+                       if not os.path.islink(x_destroot):
+                               continue
+                       try:
+                               st = os.stat(x_destroot)
+                       except OSError:
+                               continue
+                       if (st.st_dev, st.st_ino) in candidates_inodes and \
+                               x not in mycontents:
                                candidates.add(x)
 
                provider_cache = {}
@@ -2941,12 +2968,14 @@ class dblink(object):
                candidates_stack = list(candidates)
                while candidates_stack:
                        x = candidates_stack.pop()
+                       x_srcroot = os.path.join(srcroot, x.lstrip(os.path.sep))
+                       x_destroot = os.path.join(destroot, x.lstrip(os.path.sep))
                        # skip existing files so the 'new' libs aren't overwritten
                        if os.path.exists(os.path.join(srcroot, x.lstrip(os.sep))):
                                continue
                        showMessage("injecting %s into %s\n" % (x, srcroot),
                                noiselevel=-1)
-                       if not os.path.exists(os.path.join(destroot, x.lstrip(os.sep))):
+                       if not os.path.exists(x_destroot):
                                showMessage("%s does not exist so can't be preserved\n" % x,
                                        noiselevel=-1)
                                continue
@@ -2957,8 +2986,8 @@ class dblink(object):
                        # resolve symlinks and extend preserve list
                        # NOTE: we're extending the list in the loop to emulate recursion to
                        #       also get indirect symlinks
-                       if os.path.islink(x):
-                               linktarget = os.readlink(x)
+                       if os.path.islink(x_destroot):
+                               linktarget = os.readlink(x_destroot)
                                os.symlink(linktarget, os.path.join(srcroot, x.lstrip(os.sep)))
                                if linktarget[0] != os.sep:
                                        linktarget = os.path.join(os.path.dirname(x), linktarget)
@@ -2966,8 +2995,7 @@ class dblink(object):
                                        candidates.add(linktarget)
                                        candidates_stack.append(linktarget)
                        else:
-                               shutil.copy2(os.path.join(destroot, x.lstrip(os.sep)),
-                                       os.path.join(srcroot, x.lstrip(os.sep)))
+                               shutil.copy2(x_destroot, x_srcroot)
                        preserve_paths.append(x)
                        
                del candidates
index b892bb308f0e4d35b773d8349f10dcf6abf20165..a668c83246d938941e4aed7043cd547c5cd0010a 100644 (file)
@@ -2,10 +2,14 @@
 # Distributed under the terms of the GNU General Public License v2
 # $Id$
 
+__all__ = ["SETPREFIX", "get_boolean", "SetConfigError",
+       "SetConfig", "load_default_config"]
+
 import os
 from ConfigParser import SafeConfigParser, NoOptionError
 from portage import load_mod
 from portage.const import USER_CONFIG_PATH, GLOBAL_CONFIG_PATH
+from portage.exception import PackageSetNotFound
 
 SETPREFIX = "@"
 
@@ -131,7 +135,13 @@ class SetConfig(object):
                return self.psets.copy()
 
        def getSetAtoms(self, setname, ignorelist=None):
-               myset = self.getSets()[setname]
+               """
+               This raises PackageSetNotFound if the give setname does not exist.
+               """
+               try:
+                       myset = self.getSets()[setname]
+               except KeyError:
+                       raise PackageSetNotFound(setname)
                myatoms = myset.getAtoms()
                parser = self._parser
                extend = set()
@@ -150,8 +160,12 @@ class SetConfig(object):
                                                
                ignorelist.add(setname)
                for n in myset.getNonAtoms():
-                       if n.startswith(SETPREFIX) and n[len(SETPREFIX):] in self.psets:
-                               extend.add(n[len(SETPREFIX):])
+                       if n.startswith(SETPREFIX):
+                               s = n[len(SETPREFIX):]
+                               if s in self.psets:
+                                       extend.add(n[len(SETPREFIX):])
+                               else:
+                                       raise PackageSetNotFound(s)
 
                for s in ignorelist:
                        extend.discard(s)
index 5f0460e0fee51909ce39c0c96fecc87dd5a187ce..47339dee9e247fa67d1c2a6b96ccc484d176f0f0 100644 (file)
@@ -1213,7 +1213,7 @@ def new_protect_filename(mydest, newmd5=None):
                                return old_pfile
        return new_pfile
 
-def getlibpaths():
+def getlibpaths(root):
        """ Return a list of paths that are used for library lookups """
 
        # PREFIX HACK: LD_LIBRARY_PATH isn't portable, and considered
@@ -1229,11 +1229,12 @@ def getlibpaths():
        else:
                # the following is based on the information from ld.so(8)
                rval = os.environ.get("LD_LIBRARY_PATH", "").split(":")
-               rval.extend(grabfile("/etc/ld.so.conf"))
+               rval.extend(grabfile(os.path.join(root, "etc", "ld.so.conf")))
                rval.append("/usr/lib")
                rval.append("/lib")
 
-       rval = [normalize_path(x) for x in rval if x != ""]
-       
+       rval = [normalize_path(os.path.join(root, x.lstrip(os.path.sep))) \
+               for x in rval if x]
+
        return rval