| # Copyright 2010-2011 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.elog import elog_process |
| 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 will 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 |
| |
| # We must create our private PORTAGE_TMPDIR before calling |
| # doebuild_environment(), since lots of variables such |
| # as PORTAGE_BUILDDIR refer to paths inside PORTAGE_TMPDIR. |
| 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') |
| # private temp dir was just created, so it's not locked yet |
| settings.pop('PORTAGE_BUILDIR_LOCKED', None) |
| |
| try: |
| 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 |
| |
| prepare_build_dirs(settings=settings) |
| ebuild_phase = EbuildPhase(background=False, |
| phase='nofetch', scheduler=PollScheduler().sched_iface, |
| settings=settings) |
| ebuild_phase.start() |
| ebuild_phase.wait() |
| elog_process(settings.mycpv, settings) |
| finally: |
| shutil.rmtree(private_tmpdir) |