Split out parts of doebuild() so that EbuildProcess can bypass it
authorZac Medico <zmedico@gentoo.org>
Mon, 16 Aug 2010 15:16:08 +0000 (08:16 -0700)
committerZac Medico <zmedico@gentoo.org>
Mon, 16 Aug 2010 15:16:08 +0000 (08:16 -0700)
and call the spawn() function directly.

pym/_emerge/EbuildBuild.py
pym/_emerge/EbuildExecuter.py
pym/_emerge/EbuildProcess.py
pym/portage/package/ebuild/doebuild.py

index be6025a8281f9d51e37020443c0aff9a7465b521..f0fdcbdbf0f146c860c15042eaf2d7110f082ca6 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 1999-2009 Gentoo Foundation
+# Copyright 1999-2010 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 from _emerge.EbuildExecuter import EbuildExecuter
@@ -17,6 +17,8 @@ from portage import _encodings
 from portage import _unicode_encode
 import codecs
 from portage.output import colorize
+from portage.package.ebuild.doebuild import _check_temp_dir
+
 class EbuildBuild(CompositeTask):
 
        __slots__ = ("args_set", "config_pool", "find_blockers",
@@ -26,11 +28,16 @@ class EbuildBuild(CompositeTask):
 
        def _start(self):
 
-               logger = self.logger
-               opts = self.opts
                pkg = self.pkg
                settings = self.settings
-               world_atom = self.world_atom
+
+               rval = _check_temp_dir(settings)
+               if rval != os.EX_OK:
+                       self.returncode = rval
+                       self._current_task = None
+                       self.wait()
+                       return
+
                root_config = pkg.root_config
                tree = "porttree"
                self._tree = tree
@@ -176,7 +183,6 @@ class EbuildBuild(CompositeTask):
                        self.wait()
                        return
 
-               opts = self.opts
                buildpkg = self._buildpkg
 
                if not buildpkg:
@@ -259,7 +265,6 @@ class EbuildBuild(CompositeTask):
                and neither fetchonly nor buildpkgonly mode are enabled.
                """
 
-               find_blockers = self.find_blockers
                ldpath_mtimes = self.ldpath_mtimes
                logger = self.logger
                pkg = self.pkg
index 90cf401a75c41076ca5ed22736040ed38007066d..7abcbb77e788558d443ccf123e2a681c4df78859 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 1999-2009 Gentoo Foundation
+# Copyright 1999-2010 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 from _emerge.EbuildPhase import EbuildPhase
@@ -7,6 +7,8 @@ from _emerge.CompositeTask import CompositeTask
 import portage
 from portage import os
 from portage.eapi import eapi_has_src_prepare_and_src_configure
+from portage.package.ebuild.doebuild import _prepare_env_file, \
+       _prepare_fake_distdir
 
 class EbuildExecuter(CompositeTask):
 
@@ -30,8 +32,24 @@ class EbuildExecuter(CompositeTask):
                scheduler = self.scheduler
                settings = self.settings
                cleanup = 0
-
                portage.prepare_build_dirs(pkg.root, settings, cleanup)
+               rval = _prepare_env_file(settings)
+               if rval != os.EX_OK:
+                       self.returncode = rval
+                       self._current_task = None
+                       self.wait()
+                       return
+
+               portdb = pkg.root_config.trees['porttree'].dbapi
+               ebuild_path = settings['EBUILD']
+               mytree = os.path.dirname(os.path.dirname(
+                       os.path.dirname(ebuild_path)))
+               alist = portdb.getFetchMap(pkg.cpv,
+                       useflags=pkg.use.enabled, mytree=mytree)
+               aalist = portdb.getFetchMap(pkg.cpv, mytree=mytree)
+               settings.configdict["pkg"]["A"] = " ".join(alist)
+               settings.configdict["pkg"]["AA"] = " ".join(aalist)
+               _prepare_fake_distdir(settings, alist)
 
                setup_phase = EbuildPhase(background=self.background,
                        pkg=pkg, phase="setup", scheduler=scheduler,
index c643c3bd297e99a6f959b2340575599d585b2913..bd0e0d6fcfa025972697aa82dfa91f074f2ac823 100644 (file)
@@ -1,10 +1,13 @@
-# Copyright 1999-2009 Gentoo Foundation
+# Copyright 1999-2010 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 from _emerge.AbstractEbuildProcess import AbstractEbuildProcess
+from portage import _shell_quote
 from portage import os
-from portage.package.ebuild.doebuild import doebuild, \
-       _post_phase_userpriv_perms
+from portage.const import EBUILD_SH_BINARY
+from portage.package.ebuild.doebuild import  _post_phase_userpriv_perms
+from portage.package.ebuild.doebuild import spawn as doebuild_spawn
+from portage.package.ebuild.doebuild import _spawn_actionmap
 
 class EbuildProcess(AbstractEbuildProcess):
 
@@ -19,21 +22,19 @@ class EbuildProcess(AbstractEbuildProcess):
                AbstractEbuildProcess._start(self)
 
        def _spawn(self, args, **kwargs):
-
-               root_config = self.pkg.root_config
-               tree = self.tree
-               mydbapi = root_config.trees[tree].dbapi
-               vartree = root_config.trees["vartree"]
-               settings = self.settings
-               ebuild_path = settings["EBUILD"]
-               debug = settings.get("PORTAGE_DEBUG") == "1"
-               
-
-               rval = doebuild(ebuild_path, self.phase,
-                       root_config.root, settings, debug,
-                       mydbapi=mydbapi, tree=tree, vartree=vartree, **kwargs)
-
-               return rval
+               self.settings["EBUILD_PHASE"] = self.phase
+               actionmap = _spawn_actionmap(self.settings)
+               if self.phase in actionmap:
+                       kwargs.update(actionmap[self.phase]["args"])
+                       cmd = actionmap[self.phase]["cmd"] % self.phase
+               else:
+                       cmd = "%s %s" % (_shell_quote(os.path.join(
+                               self.settings["PORTAGE_BIN_PATH"],
+                               os.path.basename(EBUILD_SH_BINARY))), self.phase)
+               try:
+                       return doebuild_spawn(cmd, self.settings, **kwargs)
+               finally:
+                       self.settings.pop("EBUILD_PHASE", None)
 
        def _set_returncode(self, wait_retval):
                AbstractEbuildProcess._set_returncode(self, wait_retval)
index 90f65c4d949ad6342b5153a092370219520a9d80..bcac378d4a0c1858a4b29acb42db5c364b5642da 100644 (file)
@@ -542,40 +542,9 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                        if rval != os.EX_OK:
                                return rval
 
-               if "PORTAGE_TMPDIR" not in mysettings or \
-                       not os.path.isdir(mysettings["PORTAGE_TMPDIR"]):
-                       writemsg(_("The directory specified in your "
-                               "PORTAGE_TMPDIR variable, '%s',\n"
-                               "does not exist.  Please create this directory or "
-                               "correct your PORTAGE_TMPDIR setting.\n") % mysettings.get("PORTAGE_TMPDIR", ""), noiselevel=-1)
-                       return 1
-               
-               # as some people use a separate PORTAGE_TMPDIR mount
-               # we prefer that as the checks below would otherwise be pointless
-               # for those people.
-               if os.path.exists(os.path.join(mysettings["PORTAGE_TMPDIR"], "portage")):
-                       checkdir = os.path.join(mysettings["PORTAGE_TMPDIR"], "portage")
-               else:
-                       checkdir = mysettings["PORTAGE_TMPDIR"]
-
-               if not os.access(checkdir, os.W_OK):
-                       writemsg(_("%s is not writable.\n"
-                               "Likely cause is that you've mounted it as readonly.\n") % checkdir,
-                               noiselevel=-1)
-                       return 1
-               else:
-                       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"
-                                       "Likely cause is that you've mounted it with one of the\n"
-                                       "following mount options: 'noexec', 'user', 'users'\n\n"
-                                       "Please make sure that portage can execute files in this directory.\n") % checkdir,
-                                       noiselevel=-1)
-                               fd.close()
-                               return 1
-                       fd.close()
-               del checkdir
+               rval = _check_temp_dir(mysettings)
+               if rval != os.EX_OK:
+                       return rval
 
                if mydo == "unmerge":
                        return unmerge(mysettings["CATEGORY"],
@@ -601,66 +570,9 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                                logfile = mysettings.get("PORTAGE_LOG_FILE")
 
                if have_build_dirs:
-                       env_file = os.path.join(mysettings["T"], "environment")
-                       env_stat = None
-                       saved_env = None
-                       try:
-                               env_stat = os.stat(env_file)
-                       except OSError as e:
-                               if e.errno != errno.ENOENT:
-                                       raise
-                               del e
-                       if not env_stat:
-                               saved_env = os.path.join(
-                                       os.path.dirname(myebuild), "environment.bz2")
-                               if not os.path.isfile(saved_env):
-                                       saved_env = None
-                       if saved_env:
-                               retval = os.system(
-                                       "bzip2 -dc %s > %s" % \
-                                       (_shell_quote(saved_env),
-                                       _shell_quote(env_file)))
-                               try:
-                                       env_stat = os.stat(env_file)
-                               except OSError as e:
-                                       if e.errno != errno.ENOENT:
-                                               raise
-                                       del e
-                               if os.WIFEXITED(retval) and \
-                                       os.WEXITSTATUS(retval) == os.EX_OK and \
-                                       env_stat and env_stat.st_size > 0:
-                                       # This is a signal to ebuild.sh, so that it knows to filter
-                                       # out things like SANDBOX_{DENY,PREDICT,READ,WRITE} that
-                                       # would be preserved between normal phases.
-                                       open(_unicode_encode(env_file + '.raw'), 'w')
-                               else:
-                                       writemsg(_("!!! Error extracting saved "
-                                               "environment: '%s'\n") % \
-                                               saved_env, noiselevel=-1)
-                                       try:
-                                               os.unlink(env_file)
-                                       except OSError as e:
-                                               if e.errno != errno.ENOENT:
-                                                       raise
-                                               del e
-                                       env_stat = None
-                       if env_stat:
-                               pass
-                       else:
-                               for var in ("ARCH", ):
-                                       value = mysettings.get(var)
-                                       if value and value.strip():
-                                               continue
-                                       msg = _("%(var)s is not set... "
-                                               "Are you missing the '%(configroot)setc/make.profile' symlink? "
-                                               "Is the symlink correct? "
-                                               "Is your portage tree complete?") % \
-                                               {"var": var, "configroot": mysettings["PORTAGE_CONFIGROOT"]}
-                                       for line in wrap(msg, 70):
-                                               eerror(line, phase="setup", key=mysettings.mycpv)
-                                       elog_process(mysettings.mycpv, mysettings)
-                                       return 1
-                       del env_file, env_stat, saved_env
+                       rval = _prepare_env_file(mysettings)
+                       if rval != os.EX_OK:
+                               return rval
 
                # if any of these are being called, handle them -- running them out of
                # the sandbox -- and stop now.
@@ -807,35 +719,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
 
                # remove PORTAGE_ACTUAL_DISTDIR once cvs/svn is supported via SRC_URI
                if (mydo != "setup" and "noauto" not in features) or mydo == "unpack":
-                       orig_distdir = mysettings["DISTDIR"]
-                       mysettings["PORTAGE_ACTUAL_DISTDIR"] = orig_distdir
-                       edpath = mysettings["DISTDIR"] = \
-                               os.path.join(mysettings["PORTAGE_BUILDDIR"], "distdir")
-                       portage.util.ensure_dirs(edpath, gid=portage_gid, mode=0o755)
-
-                       # Remove any unexpected files or directories.
-                       for x in os.listdir(edpath):
-                               symlink_path = os.path.join(edpath, x)
-                               st = os.lstat(symlink_path)
-                               if x in alist and stat.S_ISLNK(st.st_mode):
-                                       continue
-                               if stat.S_ISDIR(st.st_mode):
-                                       shutil.rmtree(symlink_path)
-                               else:
-                                       os.unlink(symlink_path)
-
-                       # Check for existing symlinks and recreate if necessary.
-                       for x in alist:
-                               symlink_path = os.path.join(edpath, x)
-                               target = os.path.join(orig_distdir, x)
-                               try:
-                                       link_target = os.readlink(symlink_path)
-                               except OSError:
-                                       os.symlink(target, symlink_path)
-                               else:
-                                       if link_target != target:
-                                               os.unlink(symlink_path)
-                                               os.symlink(target, symlink_path)
+                       _prepare_fake_distdir(mysettings, alist)
 
                #initial dep checks complete; time to process main commands
                actionmap = _spawn_actionmap(mysettings)
@@ -923,6 +807,134 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                        # and the exemption is no longer needed.
                        portage._doebuild_manifest_exempt_depend -= 1
 
+def _check_temp_dir(settings):
+       if "PORTAGE_TMPDIR" not in settings or \
+               not os.path.isdir(settings["PORTAGE_TMPDIR"]):
+               writemsg(_("The directory specified in your "
+                       "PORTAGE_TMPDIR variable, '%s',\n"
+                       "does not exist.  Please create this directory or "
+                       "correct your PORTAGE_TMPDIR setting.\n") % \
+                       settings.get("PORTAGE_TMPDIR", ""), noiselevel=-1)
+               return 1
+
+       # as some people use a separate PORTAGE_TMPDIR mount
+       # we prefer that as the checks below would otherwise be pointless
+       # for those people.
+       if os.path.exists(os.path.join(settings["PORTAGE_TMPDIR"], "portage")):
+               checkdir = os.path.join(settings["PORTAGE_TMPDIR"], "portage")
+       else:
+               checkdir = settings["PORTAGE_TMPDIR"]
+
+       if not os.access(checkdir, os.W_OK):
+               writemsg(_("%s is not writable.\n"
+                       "Likely cause is that you've mounted it as readonly.\n") % checkdir,
+                       noiselevel=-1)
+               return 1
+
+       else:
+               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"
+                               "Likely cause is that you've mounted it with one of the\n"
+                               "following mount options: 'noexec', 'user', 'users'\n\n"
+                               "Please make sure that portage can execute files in this directory.\n") % checkdir,
+                               noiselevel=-1)
+                       return 1
+
+       return os.EX_OK
+
+def _prepare_env_file(settings):
+       env_file = os.path.join(settings["T"], "environment")
+       env_stat = None
+       saved_env = None
+       try:
+               env_stat = os.stat(env_file)
+       except OSError as e:
+               if e.errno != errno.ENOENT:
+                       raise
+       if not env_stat:
+               saved_env = os.path.join(
+                       os.path.dirname(settings['EBUILD']), "environment.bz2")
+               if not os.path.isfile(saved_env):
+                       saved_env = None
+       if saved_env:
+               retval = os.system(
+                       "bzip2 -dc %s > %s" % \
+                       (_shell_quote(saved_env),
+                       _shell_quote(env_file)))
+               try:
+                       env_stat = os.stat(env_file)
+               except OSError as e:
+                       if e.errno != errno.ENOENT:
+                               raise
+               if os.WIFEXITED(retval) and \
+                       os.WEXITSTATUS(retval) == os.EX_OK and \
+                       env_stat and env_stat.st_size > 0:
+                       # This is a signal to ebuild.sh, so that it knows to filter
+                       # out things like SANDBOX_{DENY,PREDICT,READ,WRITE} that
+                       # would be preserved between normal phases.
+                       open(_unicode_encode(env_file + '.raw'), 'w')
+               else:
+                       writemsg(_("!!! Error extracting saved "
+                               "environment: '%s'\n") % \
+                               saved_env, noiselevel=-1)
+                       try:
+                               os.unlink(env_file)
+                       except OSError as e:
+                               if e.errno != errno.ENOENT:
+                                       raise
+                       env_stat = None
+       if env_stat is not None:
+               pass
+       else:
+               for var in ("ARCH", ):
+                       value = settings.get(var)
+                       if value and value.strip():
+                               continue
+                       msg = _("%(var)s is not set... "
+                               "Are you missing the '%(configroot)setc/make.profile' symlink? "
+                               "Is the symlink correct? "
+                               "Is your portage tree complete?") % \
+                               {"var": var, "configroot": settings["PORTAGE_CONFIGROOT"]}
+                       for line in wrap(msg, 70):
+                               eerror(line, phase="setup", key=settings.mycpv)
+                       elog_process(settings.mycpv, settings)
+                       return 1
+
+       return os.EX_OK
+
+def _prepare_fake_distdir(settings, alist):
+       orig_distdir = settings["DISTDIR"]
+       settings["PORTAGE_ACTUAL_DISTDIR"] = orig_distdir
+       edpath = settings["DISTDIR"] = \
+               os.path.join(settings["PORTAGE_BUILDDIR"], "distdir")
+       portage.util.ensure_dirs(edpath, gid=portage_gid, mode=0o755)
+
+       # Remove any unexpected files or directories.
+       for x in os.listdir(edpath):
+               symlink_path = os.path.join(edpath, x)
+               st = os.lstat(symlink_path)
+               if x in alist and stat.S_ISLNK(st.st_mode):
+                       continue
+               if stat.S_ISDIR(st.st_mode):
+                       shutil.rmtree(symlink_path)
+               else:
+                       os.unlink(symlink_path)
+
+       # Check for existing symlinks and recreate if necessary.
+       for x in alist:
+               symlink_path = os.path.join(edpath, x)
+               target = os.path.join(orig_distdir, x)
+               try:
+                       link_target = os.readlink(symlink_path)
+               except OSError:
+                       os.symlink(target, symlink_path)
+               else:
+                       if link_target != target:
+                               os.unlink(symlink_path)
+                               os.symlink(target, symlink_path)
+
 def _spawn_actionmap(settings):
        features = settings.features
        restrict = settings["PORTAGE_RESTRICT"].split()