Bug #315615 - Use EbuildIpcDaemon to implement has_version and best_version.
authorZac Medico <zmedico@gentoo.org>
Fri, 13 Aug 2010 19:14:06 +0000 (12:14 -0700)
committerZac Medico <zmedico@gentoo.org>
Fri, 13 Aug 2010 19:14:06 +0000 (12:14 -0700)
This provides performance benefits and also avoids permissions issues with
FEATURES=userpriv.

bin/ebuild.sh
pym/_emerge/AbstractEbuildProcess.py
pym/_emerge/EbuildIpcDaemon.py
pym/_emerge/actions.py
pym/portage/package/ebuild/_ipc/QueryCommand.py [new file with mode: 0644]

index 1b1c054f177b6eca6ec451a995de7c1f8597be40..73a610b7ef6d3e615f43f64234d22ca747e01f15 100755 (executable)
@@ -159,6 +159,11 @@ has_version() {
                die "portageq calls (has_version calls portageq) are not allowed in the global scope"
        fi
 
+       if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
+               "$PORTAGE_BIN_PATH"/ebuild-ipc has_version "$ROOT" "$1" "$USE"
+               return $?
+       fi
+
        # Set EPYTHON variable as empty so that portageq doesn't try
        # to use potentially unsupported version of Python.
        EPYTHON= PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \
@@ -201,6 +206,11 @@ best_version() {
                die "portageq calls (best_version calls portageq) are not allowed in the global scope"
        fi
 
+       if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
+               "$PORTAGE_BIN_PATH"/ebuild-ipc best_version "$ROOT" "$1" "$USE"
+               return $?
+       fi
+
        # Set EPYTHON variable as empty so that portageq doesn't try
        # to use potentially unsupported version of Python.
        EPYTHON= PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \
index 57f4c8f87d762b1e76f644826be49b4e5cd8ee35..964095b2a876e464b1a1b9da0d31e8f48967145d 100644 (file)
@@ -8,6 +8,7 @@ from _emerge.EbuildIpcDaemon import EbuildIpcDaemon
 from portage.elog.messages import eerror
 from portage.localization import _
 from portage.package.ebuild._ipc.ExitCommand import ExitCommand
+from portage.package.ebuild._ipc.QueryCommand import QueryCommand
 from portage import os
 from portage import StringIO
 from portage import _encodings
@@ -44,7 +45,12 @@ class AbstractEbuildProcess(SpawnProcess):
                                self.settings['PORTAGE_BUILDDIR'], '.ipc_in')
                        output_fifo = os.path.join(
                                self.settings['PORTAGE_BUILDDIR'], '.ipc_out')
-                       commands = {'exit' : self._exit_command}
+                       query_command = QueryCommand()
+                       commands = {
+                               'best_version' : query_command,
+                               'exit'         : self._exit_command,
+                               'has_version'  : query_command,
+                       }
                        self._ipc_daemon = EbuildIpcDaemon(commands=commands,
                                input_fifo=input_fifo,
                                output_fifo=output_fifo,
index 5f3d2ed019aebb1133ada76ae399e9847539e0e6..68c68d28d827e0f569c9c8e9e1b5580059056d33 100644 (file)
@@ -59,7 +59,6 @@ class EbuildIpcDaemon(FifoIpcDaemon):
                                if reply_hook is not None:
                                        reply_hook()
 
-               self._unregister_if_appropriate(event)
                return self._registered
 
        def _send_reply(self, reply):
index 7acc9e11d5cc56e5b5fc1deed86f43237bba84e1..fb692c36357003f9fc921805c96b97470e73eaec 100644 (file)
@@ -33,6 +33,7 @@ from portage.output import blue, bold, colorize, create_color_func, darkgreen, \
        red, yellow
 good = create_color_func("GOOD")
 bad = create_color_func("BAD")
+from portage.package.ebuild._ipc.QueryCommand import QueryCommand
 from portage.sets import load_default_config, SETPREFIX
 from portage.sets.base import InternalPackageSet
 from portage.util import cmp_sort_key, writemsg, \
@@ -2774,6 +2775,7 @@ def load_emerge_config(trees=None):
        mtimedbfile = os.path.join(os.path.sep, settings['ROOT'], portage.CACHE_PATH, "mtimedb")
        mtimedb = portage.MtimeDB(mtimedbfile)
        portage.output._init(config_root=settings['PORTAGE_CONFIGROOT'])
+       QueryCommand._db = trees
        return settings, trees, mtimedb
 
 def chk_updated_cfg_files(target_root, config_protect):
diff --git a/pym/portage/package/ebuild/_ipc/QueryCommand.py b/pym/portage/package/ebuild/_ipc/QueryCommand.py
new file mode 100644 (file)
index 0000000..6848374
--- /dev/null
@@ -0,0 +1,55 @@
+# Copyright 2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import portage
+from portage import os
+from portage.dep import Atom
+from portage.exception import InvalidAtom
+from portage.package.ebuild._ipc.IpcCommand import IpcCommand
+from portage.util import normalize_path
+from portage.versions import best
+
+class QueryCommand(IpcCommand):
+
+       __slots__ = ()
+
+       _db = None
+
+       def __init__(self):
+               IpcCommand.__init__(self)
+
+       def __call__(self, argv):
+               """
+               @returns: tuple of (stdout, stderr, returncode)
+               """
+               cmd, root, atom, use = argv
+
+               try:
+                       atom = Atom(atom)
+               except InvalidAtom:
+                       return ('', 'invalid atom: %s\n' % atom, 2)
+
+               use = frozenset(use.split())
+               atom = atom.evaluate_conditionals(use)
+
+               db = self._db
+               if db is None:
+                       db = portage.db
+
+               root = normalize_path(root).rstrip(os.path.sep) + os.path.sep
+               if root not in db:
+                       return ('', 'invalid ROOT: %s\n' % root, 2)
+
+               vardb = db[root]["vartree"].dbapi
+
+               if cmd == 'has_version':
+                       if vardb.match(atom):
+                               returncode = 0
+                       else:
+                               returncode = 1
+                       return ('', '', returncode)
+               elif cmd == 'best_version':
+                       m = best(vardb.match(atom))
+                       return ('%s\n' % m, '', 0)
+               else:
+                       return ('', 'invalid command: %s\n' % cmd, 2)