Since pkg_nofetch is no longer called from fetch(), add a new
authorZac Medico <zmedico@gentoo.org>
Sat, 11 Sep 2010 03:48:49 +0000 (20:48 -0700)
committerZac Medico <zmedico@gentoo.org>
Sat, 11 Sep 2010 03:48:49 +0000 (20:48 -0700)
spawn_nofetch() support for doebuild() and other fetch() callers
to use.

pym/_emerge/EbuildPhase.py
pym/portage/package/ebuild/_spawn_nofetch.py [new file with mode: 0644]
pym/portage/package/ebuild/doebuild.py

index 9eabb340223d484571615bfc0a0f816c5e70a600..9b0a8e92451b70e9c5bcc1219128edaccc169ffe 100644 (file)
@@ -2,6 +2,7 @@
 # Distributed under the terms of the GNU General Public License v2
 
 import gzip
+import sys
 import tempfile
 
 from _emerge.BinpkgEnvExtractor import BinpkgEnvExtractor
@@ -98,8 +99,14 @@ class EbuildPhase(CompositeTask):
                if self.phase in ("clean", "cleanrm"):
                        logfile = None
 
+               fd_pipes = None
+               if not self.background and self.phase == 'nofetch':
+                       # All the pkg_nofetch output goes to stderr since
+                       # it's considered to be an error message.
+                       fd_pipes = {1 : sys.stderr.fileno()}
+
                ebuild_process = EbuildProcess(actionmap=self.actionmap,
-                       background=self.background, logfile=logfile,
+                       background=self.background, fd_pipes=fd_pipes, logfile=logfile,
                        phase=self.phase, scheduler=self.scheduler,
                        settings=self.settings)
 
diff --git a/pym/portage/package/ebuild/_spawn_nofetch.py b/pym/portage/package/ebuild/_spawn_nofetch.py
new file mode 100644 (file)
index 0000000..8de0a94
--- /dev/null
@@ -0,0 +1,75 @@
+# Copyright 2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import shutil
+import tempfile
+
+from portage import os
+from portage.const import EBUILD_PHASES
+from portage.package.ebuild.config import config
+from portage.package.ebuild.doebuild import doebuild_environment
+from portage.package.ebuild.prepare_build_dirs import prepare_build_dirs
+from _emerge.EbuildPhase import EbuildPhase
+from _emerge.PollScheduler import PollScheduler
+
+def spawn_nofetch(portdb, ebuild_path, settings=None):
+       """
+       This spawns pkg_nofetch if appropriate. The settings parameter
+       is useful only if setcpv has already been called in order
+       to cache metadata. It will be cloned internally, in order to
+       prevent any changes from interfering with the calling code.
+       If settings is None then a suitable config instance will be
+       acquired from the given portdbapi instance.
+
+       A private PORTAGE_BUILDDIR is be created and cleaned up, in
+       order to avoid any interference with any other processes.
+       If PORTAGE_TMPDIR is writable, that will be used, otherwise
+       the default directory for the tempfile module will be used.
+
+       We only call the pkg_nofetch phase if either RESTRICT=fetch
+       is set or the package has explicitly overridden the default
+       pkg_nofetch implementation. This allows specialized messages
+       to be displayed for problematic packages even though they do
+       not set RESTRICT=fetch (bug #336499).
+
+       This function does nothing if the PORTAGE_PARALLEL_FETCHONLY
+       variable is set in the config instance.
+       """
+
+       if settings is None:
+               settings = config(clone=portdb.settings)
+       else:
+               settings = config(clone=settings)
+
+       if 'PORTAGE_PARALLEL_FETCHONLY' in settings:
+               return
+
+       doebuild_environment(ebuild_path, 'nofetch',
+               settings=settings, db=portdb)
+       restrict = settings['PORTAGE_RESTRICT'].split()
+       defined_phases = settings['DEFINED_PHASES'].split()
+       if not defined_phases:
+               # When DEFINED_PHASES is undefined, assume all
+               # phases are defined.
+               defined_phases = EBUILD_PHASES
+
+       if 'fetch' not in restrict and \
+               'nofetch' not in defined_phases:
+               return
+
+       portage_tmpdir = settings.get('PORTAGE_TMPDIR')
+       if not portage_tmpdir or not os.access(portage_tmpdir, os.W_OK):
+               portage_tmpdir = None
+       private_tmpdir = tempfile.mkdtemp(dir=portage_tmpdir)
+       settings['PORTAGE_TMPDIR'] = private_tmpdir
+       settings.backup_changes('PORTAGE_TMPDIR')
+
+       try:
+               prepare_build_dirs(settings=settings)
+               ebuild_phase = EbuildPhase(background=False,
+                       phase='nofetch', scheduler=PollScheduler().sched_iface,
+                       settings=settings)
+               ebuild_phase.start()
+               ebuild_phase.wait()
+       finally:
+               shutil.rmtree(private_tmpdir)
index 6518008f02e296d511d58059efe900554d81a984..3e5587c6f67deef8bdc8b2613de4064ae71fe905 100644 (file)
@@ -25,6 +25,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
        'portage.package.ebuild.digestcheck:digestcheck',
        'portage.package.ebuild.digestgen:digestgen',
        'portage.package.ebuild.fetch:fetch',
+       'portage.package.ebuild._spawn_nofetch:spawn_nofetch',
        'portage.util.ExtractKernelVersion:ExtractKernelVersion'
 )
 
@@ -695,6 +696,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                                        fetchme = alist
                                if not fetch(fetchme, mysettings, listonly=listonly,
                                        fetchonly=fetchonly):
+                                       spawn_nofetch(mydbapi, myebuild, settings=mysettings)
                                        return 1
 
                else: