Move env_update to portage.util.env_update.envupdate.
authorZac Medico <zmedico@gentoo.org>
Thu, 25 Feb 2010 07:17:51 +0000 (07:17 -0000)
committerZac Medico <zmedico@gentoo.org>
Thu, 25 Feb 2010 07:17:51 +0000 (07:17 -0000)
svn path=/main/trunk/; revision=15452

pym/portage/__init__.py
pym/portage/dbapi/vartree.py
pym/portage/util/env_update.py [new file with mode: 0644]

index 2a0c3a6d59ff49d3a7b248c88473a1edb0e9473b..6c872af9a4e29dacdc27adc45db292bb426daa65 100644 (file)
@@ -42,8 +42,6 @@ try:
                # which is unavailable.
                from StringIO import StringIO
 
-       from time import sleep
-       from itertools import chain
        import platform
        import warnings
 
@@ -122,6 +120,7 @@ try:
                        'stack_lists,unique_array,varexpand,writedict,writemsg,' + \
                        'writemsg_stdout,write_atomic',
                'portage.util.digraph:digraph',
+               'portage.util.env_update:env_update',
                'portage.util.listdir:cacheddir,listdir',
                'portage.versions',
                'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,' + \
@@ -534,267 +533,6 @@ def abssymlink(symlink):
                mylink=mydir+"/"+mylink
        return os.path.normpath(mylink)
 
-#parse /etc/env.d and generate /etc/profile.env
-
-def env_update(makelinks=1, target_root=None, prev_mtimes=None, contents=None,
-       env=None, writemsg_level=None):
-       if writemsg_level is None:
-               writemsg_level = portage.util.writemsg_level
-       if target_root is None:
-               global settings
-               target_root = settings["ROOT"]
-       if prev_mtimes is None:
-               global mtimedb
-               prev_mtimes = mtimedb["ldpath"]
-       if env is None:
-               env = os.environ
-       envd_dir = os.path.join(target_root, "etc", "env.d")
-       portage.util.ensure_dirs(envd_dir, mode=0o755)
-       fns = listdir(envd_dir, EmptyOnError=1)
-       fns.sort()
-       templist = []
-       for x in fns:
-               if len(x) < 3:
-                       continue
-               if not x[0].isdigit() or not x[1].isdigit():
-                       continue
-               if x.startswith(".") or x.endswith("~") or x.endswith(".bak"):
-                       continue
-               templist.append(x)
-       fns = templist
-       del templist
-
-       space_separated = set(["CONFIG_PROTECT", "CONFIG_PROTECT_MASK"])
-       colon_separated = set(["ADA_INCLUDE_PATH", "ADA_OBJECTS_PATH",
-               "CLASSPATH", "INFODIR", "INFOPATH", "KDEDIRS", "LDPATH", "MANPATH",
-                 "PATH", "PKG_CONFIG_PATH", "PRELINK_PATH", "PRELINK_PATH_MASK",
-                 "PYTHONPATH", "ROOTPATH"])
-
-       config_list = []
-
-       for x in fns:
-               file_path = os.path.join(envd_dir, x)
-               try:
-                       myconfig = getconfig(file_path, expand=False)
-               except portage.exception.ParseError as e:
-                       writemsg("!!! '%s'\n" % str(e), noiselevel=-1)
-                       del e
-                       continue
-               if myconfig is None:
-                       # broken symlink or file removed by a concurrent process
-                       writemsg("!!! File Not Found: '%s'\n" % file_path, noiselevel=-1)
-                       continue
-
-               config_list.append(myconfig)
-               if "SPACE_SEPARATED" in myconfig:
-                       space_separated.update(myconfig["SPACE_SEPARATED"].split())
-                       del myconfig["SPACE_SEPARATED"]
-               if "COLON_SEPARATED" in myconfig:
-                       colon_separated.update(myconfig["COLON_SEPARATED"].split())
-                       del myconfig["COLON_SEPARATED"]
-
-       env = {}
-       specials = {}
-       for var in space_separated:
-               mylist = []
-               for myconfig in config_list:
-                       if var in myconfig:
-                               for item in myconfig[var].split():
-                                       if item and not item in mylist:
-                                               mylist.append(item)
-                               del myconfig[var] # prepare for env.update(myconfig)
-               if mylist:
-                       env[var] = " ".join(mylist)
-               specials[var] = mylist
-
-       for var in colon_separated:
-               mylist = []
-               for myconfig in config_list:
-                       if var in myconfig:
-                               for item in myconfig[var].split(":"):
-                                       if item and not item in mylist:
-                                               mylist.append(item)
-                               del myconfig[var] # prepare for env.update(myconfig)
-               if mylist:
-                       env[var] = ":".join(mylist)
-               specials[var] = mylist
-
-       for myconfig in config_list:
-               """Cumulative variables have already been deleted from myconfig so that
-               they won't be overwritten by this dict.update call."""
-               env.update(myconfig)
-
-       ldsoconf_path = os.path.join(target_root, "etc", "ld.so.conf")
-       try:
-               myld = codecs.open(_unicode_encode(ldsoconf_path,
-                       encoding=_encodings['fs'], errors='strict'),
-                       mode='r', encoding=_encodings['content'], errors='replace')
-               myldlines=myld.readlines()
-               myld.close()
-               oldld=[]
-               for x in myldlines:
-                       #each line has at least one char (a newline)
-                       if x[0]=="#":
-                               continue
-                       oldld.append(x[:-1])
-       except (IOError, OSError) as e:
-               if e.errno != errno.ENOENT:
-                       raise
-               oldld = None
-
-       ld_cache_update=False
-
-       newld = specials["LDPATH"]
-       if (oldld!=newld):
-               #ld.so.conf needs updating and ldconfig needs to be run
-               myfd = atomic_ofstream(ldsoconf_path)
-               myfd.write("# ld.so.conf autogenerated by env-update; make all changes to\n")
-               myfd.write("# contents of /etc/env.d directory\n")
-               for x in specials["LDPATH"]:
-                       myfd.write(x+"\n")
-               myfd.close()
-               ld_cache_update=True
-
-       # Update prelink.conf if we are prelink-enabled
-       if prelink_capable:
-               newprelink = atomic_ofstream(
-                       os.path.join(target_root, "etc", "prelink.conf"))
-               newprelink.write("# prelink.conf autogenerated by env-update; make all changes to\n")
-               newprelink.write("# contents of /etc/env.d directory\n")
-
-               for x in ["/bin","/sbin","/usr/bin","/usr/sbin","/lib","/usr/lib"]:
-                       newprelink.write("-l "+x+"\n");
-               for x in specials["LDPATH"]+specials["PATH"]+specials["PRELINK_PATH"]:
-                       if not x:
-                               continue
-                       if x[-1]!='/':
-                               x=x+"/"
-                       plmasked=0
-                       for y in specials["PRELINK_PATH_MASK"]:
-                               if not y:
-                                       continue
-                               if y[-1]!='/':
-                                       y=y+"/"
-                               if y==x[0:len(y)]:
-                                       plmasked=1
-                                       break
-                       if not plmasked:
-                               newprelink.write("-h "+x+"\n")
-               for x in specials["PRELINK_PATH_MASK"]:
-                       newprelink.write("-b "+x+"\n")
-               newprelink.close()
-
-       # Portage stores mtimes with 1 second granularity but in >=python-2.5 finer
-       # granularity is possible.  In order to avoid the potential ambiguity of
-       # mtimes that differ by less than 1 second, sleep here if any of the
-       # directories have been modified during the current second.
-       sleep_for_mtime_granularity = False
-       current_time = long(time.time())
-       mtime_changed = False
-       lib_dirs = set()
-       for lib_dir in portage.util.unique_array(specials["LDPATH"]+['usr/lib','usr/lib64','usr/lib32','lib','lib64','lib32']):
-               x = os.path.join(target_root, lib_dir.lstrip(os.sep))
-               try:
-                       newldpathtime = os.stat(x)[stat.ST_MTIME]
-                       lib_dirs.add(normalize_path(x))
-               except OSError as oe:
-                       if oe.errno == errno.ENOENT:
-                               try:
-                                       del prev_mtimes[x]
-                               except KeyError:
-                                       pass
-                               # ignore this path because it doesn't exist
-                               continue
-                       raise
-               if newldpathtime == current_time:
-                       sleep_for_mtime_granularity = True
-               if x in prev_mtimes:
-                       if prev_mtimes[x] == newldpathtime:
-                               pass
-                       else:
-                               prev_mtimes[x] = newldpathtime
-                               mtime_changed = True
-               else:
-                       prev_mtimes[x] = newldpathtime
-                       mtime_changed = True
-
-       if mtime_changed:
-               ld_cache_update = True
-
-       if makelinks and \
-               not ld_cache_update and \
-               contents is not None:
-               libdir_contents_changed = False
-               for mypath, mydata in contents.items():
-                       if mydata[0] not in ("obj","sym"):
-                               continue
-                       head, tail = os.path.split(mypath)
-                       if head in lib_dirs:
-                               libdir_contents_changed = True
-                               break
-               if not libdir_contents_changed:
-                       makelinks = False
-
-       ldconfig = "/sbin/ldconfig"
-       if "CHOST" in env and "CBUILD" in env and \
-               env["CHOST"] != env["CBUILD"]:
-               from portage.process import find_binary
-               ldconfig = find_binary("%s-ldconfig" % env["CHOST"])
-
-       # Only run ldconfig as needed
-       if (ld_cache_update or makelinks) and ldconfig:
-               # ldconfig has very different behaviour between FreeBSD and Linux
-               if ostype=="Linux" or ostype.lower().endswith("gnu"):
-                       # We can't update links if we haven't cleaned other versions first, as
-                       # an older package installed ON TOP of a newer version will cause ldconfig
-                       # to overwrite the symlinks we just made. -X means no links. After 'clean'
-                       # we can safely create links.
-                       writemsg_level(_(">>> Regenerating %setc/ld.so.cache...\n") % \
-                               (target_root,))
-                       if makelinks:
-                               os.system("cd / ; %s -r '%s'" % (ldconfig, target_root))
-                       else:
-                               os.system("cd / ; %s -X -r '%s'" % (ldconfig, target_root))
-               elif ostype in ("FreeBSD","DragonFly"):
-                       writemsg_level(_(">>> Regenerating %svar/run/ld-elf.so.hints...\n") % \
-                               target_root)
-                       os.system(("cd / ; %s -elf -i " + \
-                               "-f '%svar/run/ld-elf.so.hints' '%setc/ld.so.conf'") % \
-                               (ldconfig, target_root, target_root))
-
-       del specials["LDPATH"]
-
-       penvnotice  = "# THIS FILE IS AUTOMATICALLY GENERATED BY env-update.\n"
-       penvnotice += "# DO NOT EDIT THIS FILE. CHANGES TO STARTUP PROFILES\n"
-       cenvnotice  = penvnotice[:]
-       penvnotice += "# GO INTO /etc/profile NOT /etc/profile.env\n\n"
-       cenvnotice += "# GO INTO /etc/csh.cshrc NOT /etc/csh.env\n\n"
-
-       #create /etc/profile.env for bash support
-       outfile = atomic_ofstream(os.path.join(target_root, "etc", "profile.env"))
-       outfile.write(penvnotice)
-
-       env_keys = [ x for x in env if x != "LDPATH" ]
-       env_keys.sort()
-       for k in env_keys:
-               v = env[k]
-               if v.startswith('$') and not v.startswith('${'):
-                       outfile.write("export %s=$'%s'\n" % (k, v[1:]))
-               else:
-                       outfile.write("export %s='%s'\n" % (k, v))
-       outfile.close()
-
-       #create /etc/csh.env for (t)csh support
-       outfile = atomic_ofstream(os.path.join(target_root, "etc", "csh.env"))
-       outfile.write(cenvnotice)
-       for x in env_keys:
-               outfile.write("setenv %s '%s'\n" % (x, env[x]))
-       outfile.close()
-
-       if sleep_for_mtime_granularity:
-               while current_time == long(time.time()):
-                       sleep(1)
-
 def ExtractKernelVersion(base_dir):
        """
        Try to figure out what kernel version we are running
index e99bef8caeb082c5f97306fd112787e9acc0c156..80ae5bebe2f89f0fd27ec94dbe3bb1a761815097 100644 (file)
@@ -24,6 +24,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
                'writemsg,writemsg_level,write_atomic,atomic_ofstream,writedict,' + \
                'grabfile,grabdict,normalize_path,new_protect_filename,getlibpaths',
        'portage.util.digraph:digraph',
+       'portage.util.env_update:env_update',
        'portage.util.listdir:dircache,listdir',
        'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,pkgcmp,' + \
                '_pkgsplit@pkgsplit',
@@ -38,7 +39,7 @@ from portage.exception import CommandNotFound, \
        FileNotFound, PermissionDenied, UnsupportedAPIException
 from portage.localization import _
 
-from portage import dep_expand, env_update, \
+from portage import dep_expand, \
        abssymlink, movefile, _movefile, bsd_chflags
 
 # This is a special version of the os module, wrapped for unicode support.
diff --git a/pym/portage/util/env_update.py b/pym/portage/util/env_update.py
new file mode 100644 (file)
index 0000000..ebae634
--- /dev/null
@@ -0,0 +1,287 @@
+# Copyright 2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+__all__ = ['env_update']
+
+import codecs
+import errno
+import stat
+import time
+
+import portage
+from portage import os, _encodings, _unicode_encode
+from portage.checksum import prelink_capable
+from portage.data import ostype
+from portage.exception import ParseError
+from portage.localization import _
+from portage.process import find_binary
+from portage.util import atomic_ofstream, ensure_dirs, getconfig, \
+       normalize_path, writemsg
+from portage.util.listdir import listdir
+
+def env_update(makelinks=1, target_root=None, prev_mtimes=None, contents=None,
+       env=None, writemsg_level=None):
+       """
+       Parse /etc/env.d and use it to generate /etc/profile.env, csh.env,
+       ld.so.conf, and prelink.conf. Finally, run ldconfig.
+       """
+       if writemsg_level is None:
+               writemsg_level = portage.util.writemsg_level
+       if target_root is None:
+               target_root = portage.settings["ROOT"]
+       if prev_mtimes is None:
+               prev_mtimes = portage.mtimedb["ldpath"]
+       if env is None:
+               env = os.environ
+       envd_dir = os.path.join(target_root, "etc", "env.d")
+       ensure_dirs(envd_dir, mode=0o755)
+       fns = listdir(envd_dir, EmptyOnError=1)
+       fns.sort()
+       templist = []
+       for x in fns:
+               if len(x) < 3:
+                       continue
+               if not x[0].isdigit() or not x[1].isdigit():
+                       continue
+               if x.startswith(".") or x.endswith("~") or x.endswith(".bak"):
+                       continue
+               templist.append(x)
+       fns = templist
+       del templist
+
+       space_separated = set(["CONFIG_PROTECT", "CONFIG_PROTECT_MASK"])
+       colon_separated = set(["ADA_INCLUDE_PATH", "ADA_OBJECTS_PATH",
+               "CLASSPATH", "INFODIR", "INFOPATH", "KDEDIRS", "LDPATH", "MANPATH",
+                 "PATH", "PKG_CONFIG_PATH", "PRELINK_PATH", "PRELINK_PATH_MASK",
+                 "PYTHONPATH", "ROOTPATH"])
+
+       config_list = []
+
+       for x in fns:
+               file_path = os.path.join(envd_dir, x)
+               try:
+                       myconfig = getconfig(file_path, expand=False)
+               except ParseError as e:
+                       writemsg("!!! '%s'\n" % str(e), noiselevel=-1)
+                       del e
+                       continue
+               if myconfig is None:
+                       # broken symlink or file removed by a concurrent process
+                       writemsg("!!! File Not Found: '%s'\n" % file_path, noiselevel=-1)
+                       continue
+
+               config_list.append(myconfig)
+               if "SPACE_SEPARATED" in myconfig:
+                       space_separated.update(myconfig["SPACE_SEPARATED"].split())
+                       del myconfig["SPACE_SEPARATED"]
+               if "COLON_SEPARATED" in myconfig:
+                       colon_separated.update(myconfig["COLON_SEPARATED"].split())
+                       del myconfig["COLON_SEPARATED"]
+
+       env = {}
+       specials = {}
+       for var in space_separated:
+               mylist = []
+               for myconfig in config_list:
+                       if var in myconfig:
+                               for item in myconfig[var].split():
+                                       if item and not item in mylist:
+                                               mylist.append(item)
+                               del myconfig[var] # prepare for env.update(myconfig)
+               if mylist:
+                       env[var] = " ".join(mylist)
+               specials[var] = mylist
+
+       for var in colon_separated:
+               mylist = []
+               for myconfig in config_list:
+                       if var in myconfig:
+                               for item in myconfig[var].split(":"):
+                                       if item and not item in mylist:
+                                               mylist.append(item)
+                               del myconfig[var] # prepare for env.update(myconfig)
+               if mylist:
+                       env[var] = ":".join(mylist)
+               specials[var] = mylist
+
+       for myconfig in config_list:
+               """Cumulative variables have already been deleted from myconfig so that
+               they won't be overwritten by this dict.update call."""
+               env.update(myconfig)
+
+       ldsoconf_path = os.path.join(target_root, "etc", "ld.so.conf")
+       try:
+               myld = codecs.open(_unicode_encode(ldsoconf_path,
+                       encoding=_encodings['fs'], errors='strict'),
+                       mode='r', encoding=_encodings['content'], errors='replace')
+               myldlines=myld.readlines()
+               myld.close()
+               oldld=[]
+               for x in myldlines:
+                       #each line has at least one char (a newline)
+                       if x[:1] == "#":
+                               continue
+                       oldld.append(x[:-1])
+       except (IOError, OSError) as e:
+               if e.errno != errno.ENOENT:
+                       raise
+               oldld = None
+
+       ld_cache_update=False
+
+       newld = specials["LDPATH"]
+       if (oldld != newld):
+               #ld.so.conf needs updating and ldconfig needs to be run
+               myfd = atomic_ofstream(ldsoconf_path)
+               myfd.write("# ld.so.conf autogenerated by env-update; make all changes to\n")
+               myfd.write("# contents of /etc/env.d directory\n")
+               for x in specials["LDPATH"]:
+                       myfd.write(x + "\n")
+               myfd.close()
+               ld_cache_update=True
+
+       # Update prelink.conf if we are prelink-enabled
+       if prelink_capable:
+               newprelink = atomic_ofstream(
+                       os.path.join(target_root, "etc", "prelink.conf"))
+               newprelink.write("# prelink.conf autogenerated by env-update; make all changes to\n")
+               newprelink.write("# contents of /etc/env.d directory\n")
+
+               for x in ["/bin","/sbin","/usr/bin","/usr/sbin","/lib","/usr/lib"]:
+                       newprelink.write("-l %s\n" % (x,));
+               prelink_paths = []
+               prelink_paths += specials.get("LDPATH", [])
+               prelink_paths += specials.get("PATH", [])
+               prelink_paths += specials.get("PRELINK_PATH", [])
+               prelink_path_mask = specials.get("PRELINK_PATH_MASK", [])
+               for x in prelink_paths:
+                       if not x:
+                               continue
+                       if x[-1:] != '/':
+                               x += "/"
+                       plmasked = 0
+                       for y in prelink_path_mask:
+                               if not y:
+                                       continue
+                               if y[-1] != '/':
+                                       y += "/"
+                               if y == x[0:len(y)]:
+                                       plmasked = 1
+                                       break
+                       if not plmasked:
+                               newprelink.write("-h %s\n" % (x,))
+               for x in prelink_path_mask:
+                       newprelink.write("-b %s\n" % (x,))
+               newprelink.close()
+
+       # Portage stores mtimes with 1 second granularity but in >=python-2.5 finer
+       # granularity is possible.  In order to avoid the potential ambiguity of
+       # mtimes that differ by less than 1 second, sleep here if any of the
+       # directories have been modified during the current second.
+       sleep_for_mtime_granularity = False
+       current_time = long(time.time())
+       mtime_changed = False
+       lib_dirs = set()
+       for lib_dir in set(specials["LDPATH"] + \
+               ['usr/lib','usr/lib64','usr/lib32','lib','lib64','lib32']):
+               x = os.path.join(target_root, lib_dir.lstrip(os.sep))
+               try:
+                       newldpathtime = os.stat(x)[stat.ST_MTIME]
+                       lib_dirs.add(normalize_path(x))
+               except OSError as oe:
+                       if oe.errno == errno.ENOENT:
+                               try:
+                                       del prev_mtimes[x]
+                               except KeyError:
+                                       pass
+                               # ignore this path because it doesn't exist
+                               continue
+                       raise
+               if newldpathtime == current_time:
+                       sleep_for_mtime_granularity = True
+               if x in prev_mtimes:
+                       if prev_mtimes[x] == newldpathtime:
+                               pass
+                       else:
+                               prev_mtimes[x] = newldpathtime
+                               mtime_changed = True
+               else:
+                       prev_mtimes[x] = newldpathtime
+                       mtime_changed = True
+
+       if mtime_changed:
+               ld_cache_update = True
+
+       if makelinks and \
+               not ld_cache_update and \
+               contents is not None:
+               libdir_contents_changed = False
+               for mypath, mydata in contents.items():
+                       if mydata[0] not in ("obj", "sym"):
+                               continue
+                       head, tail = os.path.split(mypath)
+                       if head in lib_dirs:
+                               libdir_contents_changed = True
+                               break
+               if not libdir_contents_changed:
+                       makelinks = False
+
+       ldconfig = "/sbin/ldconfig"
+       if "CHOST" in env and "CBUILD" in env and \
+               env["CHOST"] != env["CBUILD"]:
+               ldconfig = find_binary("%s-ldconfig" % env["CHOST"])
+
+       # Only run ldconfig as needed
+       if (ld_cache_update or makelinks) and ldconfig:
+               # ldconfig has very different behaviour between FreeBSD and Linux
+               if ostype == "Linux" or ostype.lower().endswith("gnu"):
+                       # We can't update links if we haven't cleaned other versions first, as
+                       # an older package installed ON TOP of a newer version will cause ldconfig
+                       # to overwrite the symlinks we just made. -X means no links. After 'clean'
+                       # we can safely create links.
+                       writemsg_level(_(">>> Regenerating %setc/ld.so.cache...\n") % \
+                               (target_root,))
+                       if makelinks:
+                               os.system("cd / ; %s -r '%s'" % (ldconfig, target_root))
+                       else:
+                               os.system("cd / ; %s -X -r '%s'" % (ldconfig, target_root))
+               elif ostype in ("FreeBSD","DragonFly"):
+                       writemsg_level(_(">>> Regenerating %svar/run/ld-elf.so.hints...\n") % \
+                               target_root)
+                       os.system(("cd / ; %s -elf -i " + \
+                               "-f '%svar/run/ld-elf.so.hints' '%setc/ld.so.conf'") % \
+                               (ldconfig, target_root, target_root))
+
+       del specials["LDPATH"]
+
+       penvnotice  = "# THIS FILE IS AUTOMATICALLY GENERATED BY env-update.\n"
+       penvnotice += "# DO NOT EDIT THIS FILE. CHANGES TO STARTUP PROFILES\n"
+       cenvnotice  = penvnotice[:]
+       penvnotice += "# GO INTO /etc/profile NOT /etc/profile.env\n\n"
+       cenvnotice += "# GO INTO /etc/csh.cshrc NOT /etc/csh.env\n\n"
+
+       #create /etc/profile.env for bash support
+       outfile = atomic_ofstream(os.path.join(target_root, "etc", "profile.env"))
+       outfile.write(penvnotice)
+
+       env_keys = [ x for x in env if x != "LDPATH" ]
+       env_keys.sort()
+       for k in env_keys:
+               v = env[k]
+               if v.startswith('$') and not v.startswith('${'):
+                       outfile.write("export %s=$'%s'\n" % (k, v[1:]))
+               else:
+                       outfile.write("export %s='%s'\n" % (k, v))
+       outfile.close()
+
+       #create /etc/csh.env for (t)csh support
+       outfile = atomic_ofstream(os.path.join(target_root, "etc", "csh.env"))
+       outfile.write(cenvnotice)
+       for x in env_keys:
+               outfile.write("setenv %s '%s'\n" % (x, env[x]))
+       outfile.close()
+
+       if sleep_for_mtime_granularity:
+               while current_time == long(time.time()):
+                       time.sleep(1)