Add support to config.setcpv() for caching USE settings from built
authorZac Medico <zmedico@gentoo.org>
Wed, 1 Sep 2010 17:27:14 +0000 (10:27 -0700)
committerZac Medico <zmedico@gentoo.org>
Wed, 1 Sep 2010 17:27:14 +0000 (10:27 -0700)
packages, and use it for evaluating conditional USE deps in atoms
passed via IPC to helpers like has_version and best_version.

Since the pickled object that contains the IPC command will no longer
contain USE, it should solve cases that have been reported in which
large USE strings trigger poor handling of non-blocking read in
pickle.load():

Traceback (most recent call last):
  File "/usr/bin/emerge", line 43, in <module>
    retval = emerge_main()
  File "/usr/lib64/portage/pym/_emerge/main.py", line 1649, in emerge_main
    myopts, myaction, myfiles, spinner)
  File "/usr/lib64/portage/pym/_emerge/actions.py", line 437, in action_build
    retval = mergetask.merge()
  File "/usr/lib64/portage/pym/_emerge/Scheduler.py", line 1033, in merge
    rval = self._merge()
  File "/usr/lib64/portage/pym/_emerge/Scheduler.py", line 1349, in _merge
    self._main_loop()
  File "/usr/lib64/portage/pym/_emerge/Scheduler.py", line 1498, in _main_loop
    self._poll_loop()
  File "/usr/lib64/portage/pym/_emerge/PollScheduler.py", line 139, in _poll_loop
    handler(f, event)
  File "/usr/lib64/portage/pym/_emerge/EbuildIpcDaemon.py", line 36, in _input_handler
    obj = pickle.load(self._files.pipe_in)
  File "/usr/lib64/python2.6/pickle.py", line 1370, in load
    return Unpickler(file).load()
  File "/usr/lib64/python2.6/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib64/python2.6/pickle.py", line 1195, in load_setitem
    value = stack.pop()
IndexError: pop from empty list

bin/ebuild.sh
pym/portage/package/ebuild/_config/special_env_vars.py
pym/portage/package/ebuild/_ipc/QueryCommand.py
pym/portage/package/ebuild/config.py

index 1428ac8d2ba96dcfdf00660151808fccce29a2a3..b3b23aabb8d2ab5e62fe4dfaed9e9f938111cb07 100755 (executable)
@@ -166,7 +166,7 @@ has_version() {
        fi
 
        if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
-               "$PORTAGE_BIN_PATH"/ebuild-ipc has_version "$ROOT" "$1" "$USE"
+               "$PORTAGE_BIN_PATH"/ebuild-ipc has_version "$ROOT" "$1"
                return $?
        fi
 
@@ -209,7 +209,7 @@ best_version() {
        fi
 
        if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
-               "$PORTAGE_BIN_PATH"/ebuild-ipc best_version "$ROOT" "$1" "$USE"
+               "$PORTAGE_BIN_PATH"/ebuild-ipc best_version "$ROOT" "$1"
                return $?
        fi
 
index 4a29b1446cad86adb7988e6bd5586f7f58cfd8cc..4ad4a0e9ac48a8d642df34b4d639e95e22561668 100644 (file)
@@ -13,7 +13,7 @@ env_blacklist = frozenset((
        "EBUILD_PHASE", "ED", "EMERGE_FROM", "EPREFIX", "EROOT",
        "HOMEPAGE", "INHERITED", "IUSE",
        "KEYWORDS", "LICENSE", "PDEPEND", "PF", "PKGUSE",
-       "PORTAGE_CONFIGROOT", "PORTAGE_IUSE",
+       "PORTAGE_BUILT_USE", "PORTAGE_CONFIGROOT", "PORTAGE_IUSE",
        "PORTAGE_NONFATAL", "PORTAGE_REPO_NAME",
        "PORTAGE_USE", "PROPERTIES", "PROVIDE", "RDEPEND", "RESTRICT",
        "ROOT", "SLOT", "SRC_URI"
index ec52e400f26af81f70bdaa8d17d4d4f0635c499f..1afe886aa84dfbc4468e7fa4a5123218f8330955 100644 (file)
@@ -24,18 +24,17 @@ class QueryCommand(IpcCommand):
                @returns: tuple of (stdout, stderr, returncode)
                """
 
-               # Note that $USE is passed via IPC in order to ensure that
-               # we have the correct value for built/installed packages,
-               # since the config class doesn't currently provide a way
-               # to access built/installed $USE that would work in all
-               # possible scenarios.
-               cmd, root, atom, use = argv
+               cmd, root, atom = argv
 
                try:
                        atom = Atom(atom)
                except InvalidAtom:
                        return ('', 'invalid atom: %s\n' % atom, 2)
 
+               use = self.settings.get('PORTAGE_BUILT_USE')
+               if use is None:
+                       use = self.settings['PORTAGE_USE']
+
                use = frozenset(use.split())
                atom = atom.evaluate_conditionals(use)
 
index cf2586f6ce57705ec4a4f615a37acfcbe3bd0e89..443a735eb8101167ce31dc499ca38352a5adea3c 100644 (file)
@@ -1147,8 +1147,20 @@ class config(object):
                                                pkg_configdict.addLazySingleton(k,
                                                        mydb.__getitem__, k)
                        else:
+                               # When calling dbapi.aux_get(), grab USE for built/installed
+                               # packages since we want to save it PORTAGE_BUILT_USE for
+                               # evaluating conditional USE deps in atoms passed via IPC to
+                               # helpers like has_version and best_version.
+                               aux_keys = list(aux_keys)
+                               aux_keys.append('USE')
                                for k, v in zip(aux_keys, mydb.aux_get(self.mycpv, aux_keys)):
                                        pkg_configdict[k] = v
+                               built_use = frozenset(pkg_configdict.pop('USE').split())
+                               if not built_use:
+                                       # Empty USE means this dbapi instance does not contain
+                                       # built packages.
+                                       built_use = None
+
                        repository = pkg_configdict.pop("repository", None)
                        if repository is not None:
                                pkg_configdict["PORTAGE_REPO_NAME"] = repository
@@ -1258,6 +1270,9 @@ class config(object):
                env_configdict.addLazySingleton('PORTAGE_RESTRICT',
                        lazy_vars.__getitem__, 'PORTAGE_RESTRICT')
 
+               if built_use is not None:
+                       pkg_configdict['PORTAGE_BUILT_USE'] = ' '.join(built_use)
+
                # If reset() has not been called, it's safe to return
                # early if IUSE has not changed.
                if not has_changed and previous_iuse == iuse: