Merged from trunk -r15507:15517
authorFabian Groffen <grobian@gentoo.org>
Wed, 3 Mar 2010 18:46:26 +0000 (18:46 -0000)
committerFabian Groffen <grobian@gentoo.org>
Wed, 3 Mar 2010 18:46:26 +0000 (18:46 -0000)
   | 15508   | Move imports to the top and use writemsg_stdout instead of   |
   | zmedico | print().                                                     |

   | 15509   | Use writemsg instead of print. Also don't use _ as a         |
   | zmedico | variable name since it collides with _ from                  |
   |         | portage.localization.                                        |

   | 15510   | Add a note in _find_system_deps about needing the system set |
   | zmedico | added to the graph.                                          |

   | 15511   | Fix legacy globals proxies to reset state when the portage   |
   | zmedico | module is reloaded. This fixes ebuild(1) failing to generate |
   |         | manifests when the ebuild is not in PORTDIR_OVERLAY, as      |
   |         | reported by Arfrever.                                        |

   | 15512   | Test for python openpty breakage after freebsd7 to freebsd8  |
   | zmedico | upgrade, which results in a 'Function not implemented' error |
   |         | and the process being killed. Thanks to Javier               |
   |         | Villavicenciom <the_paya@g.o> for reporting and helping to   |
   |         | develop this test.                                           |

   | 15513   | Bug #306659 - For --rebuilt-binaries, only reinstall if      |
   | zmedico | binary package BUILD_TIME is non-empty, in order to avoid    |
   |         | cases like to bug #306659 where BUILD_TIME fields are        |
   |         | missing in local and/or remote Packages file.                |

   | 15514   | Move imports to top.                                         |
   | zmedico |                                                              |

   | 15515   | Move _pty module to portage.util._pty.                       |
   | zmedico |                                                              |

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

pym/_emerge/AbstractEbuildProcess.py
pym/_emerge/EbuildFetcher.py
pym/_emerge/Scheduler.py
pym/_emerge/depgraph.py
pym/portage/__init__.py
pym/portage/_legacy_globals.py
pym/portage/dbapi/vartree.py
pym/portage/package/ebuild/doebuild.py
pym/portage/tests/ebuild/test_pty_eof.py
pym/portage/util/_pty.py [moved from pym/portage/package/ebuild/_pty.py with 89% similarity]

index 0d8be6fbfbc7b4c306d424f8ada6a45007548fd8..64846ff8c897aa8fe80f279c263dd0c7ae0e90db 100644 (file)
@@ -5,7 +5,7 @@
 from _emerge.SpawnProcess import SpawnProcess
 import portage
 from portage import os
-from portage.package.ebuild._pty import _create_pty_or_pipe
+from portage.util._pty import _create_pty_or_pipe
 
 class AbstractEbuildProcess(SpawnProcess):
 
index b2ba07bcd14c4003b2058e6c03057c069f18121a..14c3484832277a39d2569095ea16633f9b585834 100644 (file)
@@ -13,7 +13,7 @@ from portage import _encodings
 from portage import _unicode_encode
 import codecs
 from portage.elog.messages import eerror
-from portage.package.ebuild._pty import _create_pty_or_pipe
+from portage.util._pty import _create_pty_or_pipe
 
 class EbuildFetcher(SpawnProcess):
 
index 0f113416f3cd51f38568f354c86d57e553ff0471..a97adc04131a9f8ec863b8843d78a2ce1a8f6866 100644 (file)
@@ -357,6 +357,9 @@ class Scheduler(PollScheduler):
                Find system packages and their deep runtime dependencies. Before being
                merged, these packages go to merge_wait_queue, to be merged when no
                other packages are building.
+               NOTE: This can only find deep system deps if the system set has been
+               added to the graph and traversed deeply (the depgraph "complete"
+               parameter will do this, triggered by emerge --complete-graph option).
                """
                deep_system_deps = self._deep_system_deps
                deep_system_deps.clear()
index 73ff21cf81957df1521029dabb4960a8e050602e..831b6e81f8854849097e608ebe07f0313c6de8e7 100644 (file)
@@ -2640,8 +2640,13 @@ class depgraph(object):
                                        elif pkg.built:
                                                built_pkg = pkg
                                if built_pkg is not None and inst_pkg is not None:
-                                       if built_pkg.metadata['BUILD_TIME'] != \
-                                               inst_pkg.metadata['BUILD_TIME']:
+                                       # Only reinstall if binary package BUILD_TIME is
+                                       # non-empty, in order to avoid cases like to
+                                       # bug #306659 where BUILD_TIME fields are missing
+                                       # in local and/or remote Packages file.
+                                       if built_pkg.metadata['BUILD_TIME'] and \
+                                               (built_pkg.metadata['BUILD_TIME'] != \
+                                               inst_pkg.metadata['BUILD_TIME']):
                                                return built_pkg, built_pkg
 
                        if avoid_update:
index 8309fb03c5ca4aa56ea625df7559e58e66906bde..6679555a1a54eb86b285a214e35f7c4f6460d9b7 100644 (file)
@@ -575,6 +575,8 @@ for k in _legacy_global_var_names:
        globals()[k] = _LegacyGlobalProxy(k)
 del k
 
+_legacy_globals_constructed = set()
+
 def _disable_legacy_globals():
        """
        This deletes the ObjectProxy instances that are used
index f524cbe387be6d4694dcce11dfc461ed558dea3c..19fce20d1737b486ecc0c02478def2d86892b4b0 100644 (file)
@@ -6,25 +6,23 @@ import portage
 from portage import os
 from portage.const import CACHE_PATH, PROFILE_PATH
 
-_legacy_globals = {}
-
 def _get_legacy_global(name):
-       global _legacy_globals
-       target = _legacy_globals.get(name, _legacy_globals)
-       if target is not _legacy_globals:
-               return target
+       constructed = portage._legacy_globals_constructed
+       if name in constructed:
+               return getattr(portage, name)
 
        if name == 'portdb':
                portage.portdb = portage.db[portage.root]["porttree"].dbapi
-               _legacy_globals[name] = portage.portdb
-               return _legacy_globals[name]
+               constructed.add(name)
+               return getattr(portage, name)
+
        elif name in ('mtimedb', 'mtimedbfile'):
                portage.mtimedbfile = os.path.join(portage.root,
                        CACHE_PATH, "mtimedb")
-               _legacy_globals['mtimedbfile'] = portage.mtimedbfile
+               constructed.add('mtimedbfile')
                portage.mtimedb = portage.MtimeDB(portage.mtimedbfile)
-               _legacy_globals['mtimedb'] = portage.mtimedb
-               return _legacy_globals[name]
+               constructed.add('mtimedb')
+               return getattr(portage, name)
 
        # Portage needs to ensure a sane umask for the files it creates.
        os.umask(0o22)
@@ -35,7 +33,7 @@ def _get_legacy_global(name):
 
        portage._initializing_globals = True
        portage.db = portage.create_trees(**kwargs)
-       _legacy_globals['db'] = portage.db
+       constructed.add('db')
        del portage._initializing_globals
 
        settings = portage.db["/"]["vartree"].settings
@@ -48,40 +46,40 @@ def _get_legacy_global(name):
        portage.output._init(config_root=settings['PORTAGE_CONFIGROOT'])
 
        portage.settings = settings
-       _legacy_globals['settings'] = settings
+       constructed.add('settings')
 
        portage.root = root
-       _legacy_globals['root'] = root
+       constructed.add('root')
 
        # COMPATIBILITY
        # These attributes should not be used within
        # Portage under any circumstances.
 
        portage.archlist = settings.archlist()
-       _legacy_globals['archlist'] = portage.archlist
+       constructed.add('archlist')
 
        portage.features = settings.features
-       _legacy_globals['features'] = portage.features
+       constructed.add('features')
 
        portage.groups = settings["ACCEPT_KEYWORDS"].split()
-       _legacy_globals['groups'] = portage.groups
+       constructed.add('groups')
 
        portage.pkglines = settings.packages
-       _legacy_globals['pkglines'] = portage.pkglines
+       constructed.add('pkglines')
 
        portage.selinux_enabled = settings.selinux_enabled()
-       _legacy_globals['selinux_enabled'] = portage.selinux_enabled
+       constructed.add('selinux_enabled')
 
        portage.thirdpartymirrors = settings.thirdpartymirrors()
-       _legacy_globals['thirdpartymirrors'] = portage.thirdpartymirrors
+       constructed.add('thirdpartymirrors')
 
        portage.usedefaults = settings.use_defs
-       _legacy_globals['usedefaults'] = portage.usedefaults
+       constructed.add('usedefaults')
 
        profiledir = os.path.join(settings["PORTAGE_CONFIGROOT"], PROFILE_PATH)
        if not os.path.isdir(profiledir):
                profiledir = None
        portage.profiledir = profiledir
-       _legacy_globals['profiledir'] = portage.profiledir
+       constructed.add('profiledir')
 
-       return _legacy_globals[name]
+       return getattr(portage, name)
index 1e1d6c693155534318f67f4d56195ad11ebdad06..5f4c43720216c9d995f88a16c4761aa4b6a00908 100644 (file)
@@ -2,8 +2,6 @@
 # Distributed under the terms of the GNU General Public License v2
 # $Id$
 
-from __future__ import print_function
-
 __all__ = ["PreservedLibsRegistry", "LinkageMap",
        "LinkageMapMachO", "LinkageMapPeCoff", "LinkageMapXCoff"
        "vardbapi", "vartree", "dblink"] + \
@@ -501,7 +499,7 @@ class LinkageMap(object):
                                        if obj_key.file_exists():
                                                # Get the arch and soname from LinkageMap._obj_properties if
                                                # it exists. Otherwise, None.
-                                               arch, _, _, soname, _ = \
+                                               arch, _needed, _path, soname, _objs = \
                                                                self._obj_properties.get(obj_key, (None,)*5)
                                                return cache_self.cache.setdefault(obj, \
                                                                (arch, soname, obj_key, True))
@@ -515,7 +513,7 @@ class LinkageMap(object):
 
                # Iterate over all obj_keys and their providers.
                for obj_key, sonames in providers.items():
-                       arch, _, path, _, objs = self._obj_properties[obj_key]
+                       arch, _needed, path, _soname, objs = self._obj_properties[obj_key]
                        path = path.union(self._defpath)
                        # Iterate over each needed soname and the set of library paths that
                        # fulfill the soname to determine if the dependency is broken.
@@ -545,19 +543,23 @@ class LinkageMap(object):
                                                        # XXX This is most often due to soname symlinks not in
                                                        # a library's directory.  We could catalog symlinks in
                                                        # LinkageMap to avoid checking for this edge case here.
-                                                       print(_("Found provider outside of findProviders:"), \
-                                                                       os.path.join(directory, soname), "->", \
-                                                                       self._obj_properties[cachedKey][4], libraries)
+                                                       writemsg(
+                                                               _("Found provider outside of findProviders:") + \
+                                                               (" %s -> %s %s\n" % (os.path.join(directory, soname),
+                                                               self._obj_properties[cachedKey][4], libraries)),
+                                                               noiselevel=-1)
                                                # A valid library has been found, so there is no need to
                                                # continue.
                                                break
                                        if debug and cachedArch == arch and \
                                                        cachedKey in self._obj_properties:
-                                               print(_("Broken symlink or missing/bad soname: %(dir_soname)s -> %(cachedKey)s "
+                                               writemsg((_("Broken symlink or missing/bad soname: " + \
+                                                       "%(dir_soname)s -> %(cachedKey)s " + \
                                                        "with soname %(cachedSoname)s but expecting %(soname)s") % \
                                                        {"dir_soname":os.path.join(directory, soname),
                                                        "cachedKey": self._obj_properties[cachedKey],
-                                                       "cachedSoname": cachedSoname, "soname":soname})
+                                                       "cachedSoname": cachedSoname, "soname":soname}) + "\n",
+                                                       noiselevel=-1)
                                # This conditional checks if there are no libraries to satisfy the
                                # soname (empty set).
                                if not validLibraries:
@@ -573,10 +575,12 @@ class LinkageMap(object):
                                                rValue.setdefault(lib, set()).add(soname)
                                                if debug:
                                                        if not os.path.isfile(lib):
-                                                               print(_("Missing library:"), lib)
+                                                               writemsg(_("Missing library:") + " %s\n" % (lib,),
+                                                                       noiselevel=-1)
                                                        else:
-                                                               print(_("Possibly missing symlink:"), \
-                                                                               os.path.join(os.path.dirname(lib), soname))
+                                                               writemsg(_("Possibly missing symlink:") + \
+                                                                       "%s\n" % (os.path.join(os.path.dirname(lib), soname)),
+                                                                       noiselevel=-1)
                return rValue
 
        def listProviders(self):
@@ -696,7 +700,7 @@ class LinkageMap(object):
                        if obj_key not in self._obj_properties:
                                raise KeyError("%s (%s) not in object list" % (obj_key, obj))
 
-               arch, needed, path, _, _ = self._obj_properties[obj_key]
+               arch, needed, path, _soname, _objs = self._obj_properties[obj_key]
                path_keys = set(self._path_key(x) for x in path.union(self._defpath))
                for soname in needed:
                        rValue[soname] = set()
@@ -783,12 +787,12 @@ class LinkageMap(object):
                objs_dir_keys = set(self._path_key(os.path.dirname(x)) for x in objs)
                defpath_keys = set(self._path_key(x) for x in self._defpath)
 
-               arch, _, _, soname, _ = self._obj_properties[obj_key]
+               arch, _needed, _path, soname, _objs = self._obj_properties[obj_key]
                if arch in self._libs and soname in self._libs[arch]:
                        # For each potential consumer, add it to rValue if an object from the
                        # arguments resides in the consumer's runpath.
                        for consumer_key in self._libs[arch][soname].consumers:
-                               _, _, path, _, consumer_objs = \
+                               _arch, _needed, path, _soname, consumer_objs = \
                                                self._obj_properties[consumer_key]
                                path_keys = defpath_keys.union(self._path_key(x) for x in path)
                                if objs_dir_keys.intersection(path_keys):
index a900758b6c50ea3672034fbbb427403fb8486268..c7f852f07525631b0b165ce19f9382c2b51bf7a6 100644 (file)
@@ -2,19 +2,21 @@
 # Distributed under the terms of the GNU General Public License v2
 # $Id$
 
-from __future__ import print_function
-
 __all__ = ['doebuild', 'doebuild_environment', 'spawn', 'spawnebuild']
 
+import array
 import codecs
 import errno
+import fcntl
 from itertools import chain
 import logging
 import os as _os
 import re
+import select
 import shutil
 import stat
 import sys
+import tempfile
 from textwrap import wrap
 import time
 
@@ -47,10 +49,10 @@ from portage.manifest import Manifest
 from portage.output import style_to_ansi_code
 from portage.package.ebuild.fetch import fetch
 from portage.package.ebuild.prepare_build_dirs import prepare_build_dirs
-from portage.package.ebuild._pty import _create_pty_or_pipe
 from portage.util import apply_recursive_permissions, \
        apply_secpass_permissions, noiselimit, normalize_path, \
        writemsg, writemsg_stdout, write_atomic
+from portage.util._pty import _create_pty_or_pipe
 from portage.versions import _pkgsplit
 
 def doebuild_environment(myebuild, mydo, myroot, mysettings,
@@ -525,8 +527,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                # so that there's no need for locking and it can be used even if the
                # user isn't in the portage group.
                if mydo in ("info",):
-                       from tempfile import mkdtemp
-                       tmpdir = mkdtemp()
+                       tmpdir = tempfile.mkdtemp()
                        tmpdir_orig = mysettings["PORTAGE_TMPDIR"]
                        mysettings["PORTAGE_TMPDIR"] = tmpdir
 
@@ -622,8 +623,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                                noiselevel=-1)
                        return 1
                else:
-                       from tempfile import NamedTemporaryFile
-                       fd = NamedTemporaryFile(prefix="exectest-", dir=checkdir)
+                       fd = tempfile.NamedTemporaryFile(prefix="exectest-", dir=checkdir)
                        os.chmod(fd.name, 0o755)
                        if not os.access(fd.name, os.X_OK):
                                writemsg(_("Can not execute files in %s\n"
@@ -1004,7 +1004,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                                        myebuild=mysettings["EBUILD"], mytree=tree, mydbapi=mydbapi,
                                        vartree=vartree, prev_mtimes=prev_mtimes)
                else:
-                       print(_("!!! Unknown mydo: %s") % mydo)
+                       writemsg_stdout(_("!!! Unknown mydo: %s\n") % mydo, noiselevel=-1)
                        return 1
 
                return retval
@@ -1190,7 +1190,6 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero
                # process might have already exited and closed slave_fd so we
                # have to keep it open in order to avoid FreeBSD potentially
                # generating an EAGAIN exception).
-               import fcntl
                fcntl.fcntl(master_fd, fcntl.F_SETFL,
                        fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)
 
@@ -1250,7 +1249,6 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero
                iwtd = [master_file]
                owtd = []
                ewtd = []
-               import array, select
                buffsize = 65536
                eof = False
                while not eof:
index b29c8f95f4c946c5af01d82e20b055a378d95a9a..6280eb263b905277cf3094ee7066936a6bba1f5f 100644 (file)
@@ -4,7 +4,7 @@
 
 import portage
 from portage.tests import TestCase
-from portage.package.ebuild._pty import _can_test_pty_eof, _test_pty_eof
+from portage.util._pty import _can_test_pty_eof, _test_pty_eof
 
 class PtyEofTestCase(TestCase):
 
similarity index 89%
rename from pym/portage/package/ebuild/_pty.py
rename to pym/portage/util/_pty.py
index 7cc1e4422f59e326bb6ce2e36d43da3779cccafb..c48584f58f313c2275823dbfd59ce4b748a9eab0 100644 (file)
@@ -11,6 +11,7 @@ import sys
 import termios
 
 from portage import os, _unicode_decode, _unicode_encode
+from portage.output import get_term_size, set_term_size
 from portage.process import spawn_bash
 from portage.util import writemsg
 
@@ -132,6 +133,8 @@ if not _can_test_pty_eof():
        # Skip _test_pty_eof() on systems where it hangs.
        _tested_pty = True
 
+_fbsd_test_pty = platform.system() == 'FreeBSD'
+
 def _create_pty_or_pipe(copy_term_size=None):
        """
        Try to create a pty and if then fails then create a normal
@@ -148,7 +151,7 @@ def _create_pty_or_pipe(copy_term_size=None):
 
        got_pty = False
 
-       global _disable_openpty, _tested_pty
+       global _disable_openpty, _fbsd_test_pty, _tested_pty
        if not (_tested_pty or _disable_openpty):
                try:
                        if not _test_pty_eof():
@@ -160,12 +163,24 @@ def _create_pty_or_pipe(copy_term_size=None):
                        del e
                _tested_pty = True
 
+       if _fbsd_test_pty and not _disable_openpty:
+               # Test for python openpty breakage after freebsd7 to freebsd8
+               # upgrade, which results in a 'Function not implemented' error
+               # and the process being killed.
+               pid = os.fork()
+               if pid == 0:
+                       pty.openpty()
+                       os._exit(os.EX_OK)
+               pid, status = os.waitpid(pid, 0)
+               if (status & 0xff) == 140:
+                       _disable_openpty = True
+               _fbsd_test_pty = False
+
        if _disable_openpty:
                master_fd, slave_fd = os.pipe()
        else:
-               from pty import openpty
                try:
-                       master_fd, slave_fd = openpty()
+                       master_fd, slave_fd = pty.openpty()
                        got_pty = True
                except EnvironmentError as e:
                        _disable_openpty = True
@@ -177,7 +192,6 @@ def _create_pty_or_pipe(copy_term_size=None):
        if got_pty:
                # Disable post-processing of output since otherwise weird
                # things like \n -> \r\n transformations may occur.
-               import termios
                mode = termios.tcgetattr(slave_fd)
                mode[1] &= ~termios.OPOST
                termios.tcsetattr(slave_fd, termios.TCSANOW, mode)
@@ -185,7 +199,6 @@ def _create_pty_or_pipe(copy_term_size=None):
        if got_pty and \
                copy_term_size is not None and \
                os.isatty(copy_term_size):
-               from portage.output import get_term_size, set_term_size
                rows, columns = get_term_size()
                set_term_size(rows, columns, slave_fd)