summaryrefslogtreecommitdiffstats
path: root/pym/_emerge/EbuildMetadataPhase.py
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2009-06-22 16:43:52 +0000
committerZac Medico <zmedico@gentoo.org>2009-06-22 16:43:52 +0000
commitd057d91f391981fb0564873c471d550f2f62edf5 (patch)
treed6cd416fc5e9389806ec98a02ae236c99e876e4b /pym/_emerge/EbuildMetadataPhase.py
parent28184c982a0688ed9bc4d82df407d4e400f6318c (diff)
downloadportage-d057d91f391981fb0564873c471d550f2f62edf5.tar.gz
portage-d057d91f391981fb0564873c471d550f2f62edf5.tar.bz2
portage-d057d91f391981fb0564873c471d550f2f62edf5.zip
Bug #275047 - Split _emerge/__init__.py into smaller pieces. Thanks to
Sebastian Mingramm (few) <s.mingramm@gmx.de> for this patch. svn path=/main/trunk/; revision=13663
Diffstat (limited to 'pym/_emerge/EbuildMetadataPhase.py')
-rw-r--r--pym/_emerge/EbuildMetadataPhase.py132
1 files changed, 132 insertions, 0 deletions
diff --git a/pym/_emerge/EbuildMetadataPhase.py b/pym/_emerge/EbuildMetadataPhase.py
new file mode 100644
index 000000000..54707f424
--- /dev/null
+++ b/pym/_emerge/EbuildMetadataPhase.py
@@ -0,0 +1,132 @@
+from _emerge.SubProcess import SubProcess
+from _emerge.PollConstants import PollConstants
+import sys
+from portage.cache.mappings import slot_dict_class
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ import sys
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+import os
+from itertools import izip
+import fcntl
+import codecs
+class EbuildMetadataPhase(SubProcess):
+
+ """
+ Asynchronous interface for the ebuild "depend" phase which is
+ used to extract metadata from the ebuild.
+ """
+
+ __slots__ = ("cpv", "ebuild_path", "fd_pipes", "metadata_callback",
+ "ebuild_mtime", "metadata", "portdb", "repo_path", "settings") + \
+ ("_raw_metadata",)
+
+ _file_names = ("ebuild",)
+ _files_dict = slot_dict_class(_file_names, prefix="")
+ _metadata_fd = 9
+
+ def _start(self):
+ settings = self.settings
+ settings.setcpv(self.cpv)
+ ebuild_path = self.ebuild_path
+
+ eapi = None
+ if 'parse-eapi-glep-55' in settings.features:
+ pf, eapi = portage._split_ebuild_name_glep55(
+ os.path.basename(ebuild_path))
+ if eapi is None and \
+ 'parse-eapi-ebuild-head' in settings.features:
+ eapi = portage._parse_eapi_ebuild_head(codecs.open(ebuild_path,
+ mode='r', encoding='utf_8', errors='replace'))
+
+ if eapi is not None:
+ if not portage.eapi_is_supported(eapi):
+ self.metadata_callback(self.cpv, self.ebuild_path,
+ self.repo_path, {'EAPI' : eapi}, self.ebuild_mtime)
+ self.returncode = os.EX_OK
+ self.wait()
+ return
+
+ settings.configdict['pkg']['EAPI'] = eapi
+
+ debug = settings.get("PORTAGE_DEBUG") == "1"
+ master_fd = None
+ slave_fd = None
+ fd_pipes = None
+ if self.fd_pipes is not None:
+ fd_pipes = self.fd_pipes.copy()
+ else:
+ fd_pipes = {}
+
+ fd_pipes.setdefault(0, sys.stdin.fileno())
+ fd_pipes.setdefault(1, sys.stdout.fileno())
+ fd_pipes.setdefault(2, sys.stderr.fileno())
+
+ # flush any pending output
+ for fd in fd_pipes.itervalues():
+ if fd == sys.stdout.fileno():
+ sys.stdout.flush()
+ if fd == sys.stderr.fileno():
+ sys.stderr.flush()
+
+ fd_pipes_orig = fd_pipes.copy()
+ self._files = self._files_dict()
+ files = self._files
+
+ master_fd, slave_fd = os.pipe()
+ fcntl.fcntl(master_fd, fcntl.F_SETFL,
+ fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)
+
+ fd_pipes[self._metadata_fd] = slave_fd
+
+ self._raw_metadata = []
+ files.ebuild = os.fdopen(master_fd, 'r')
+ self._reg_id = self.scheduler.register(files.ebuild.fileno(),
+ self._registered_events, self._output_handler)
+ self._registered = True
+
+ retval = portage.doebuild(ebuild_path, "depend",
+ settings["ROOT"], settings, debug,
+ mydbapi=self.portdb, tree="porttree",
+ fd_pipes=fd_pipes, returnpid=True)
+
+ os.close(slave_fd)
+
+ if isinstance(retval, int):
+ # doebuild failed before spawning
+ self._unregister()
+ self.returncode = retval
+ self.wait()
+ return
+
+ self.pid = retval[0]
+ portage.process.spawned_pids.remove(self.pid)
+
+ def _output_handler(self, fd, event):
+
+ if event & PollConstants.POLLIN:
+ self._raw_metadata.append(self._files.ebuild.read())
+ if not self._raw_metadata[-1]:
+ self._unregister()
+ self.wait()
+
+ self._unregister_if_appropriate(event)
+ return self._registered
+
+ def _set_returncode(self, wait_retval):
+ SubProcess._set_returncode(self, wait_retval)
+ if self.returncode == os.EX_OK:
+ metadata_lines = "".join(self._raw_metadata).splitlines()
+ if len(portage.auxdbkeys) != len(metadata_lines):
+ # Don't trust bash's returncode if the
+ # number of lines is incorrect.
+ self.returncode = 1
+ else:
+ metadata = izip(portage.auxdbkeys, metadata_lines)
+ self.metadata = self.metadata_callback(self.cpv,
+ self.ebuild_path, self.repo_path, metadata,
+ self.ebuild_mtime)
+