public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "André Erdmann" <dywi@mailerd.de>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/portage/
Date: Fri, 15 Jun 2012 20:34:30 +0000 (UTC)	[thread overview]
Message-ID: <1339754001.2e3c050d5712b079611af4d21b9869817fba05b7.dywi@gentoo> (raw)

commit:     2e3c050d5712b079611af4d21b9869817fba05b7
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jun 15 09:53:21 2012 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jun 15 09:53:21 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=2e3c050d

manifest creation

* real implementation in manifesthelpers.py,
  easy access via manifest.py->creat_manifest()

	modified:   roverlay/portage/manifest.py
	new file:   roverlay/portage/manifesthelpers.py

---
 roverlay/portage/manifest.py        |  145 +++----------------------
 roverlay/portage/manifesthelpers.py |  207 +++++++++++++++++++++++++++++++++++
 2 files changed, 223 insertions(+), 129 deletions(-)

diff --git a/roverlay/portage/manifest.py b/roverlay/portage/manifest.py
index a74226b..79e241c 100644
--- a/roverlay/portage/manifest.py
+++ b/roverlay/portage/manifest.py
@@ -3,143 +3,30 @@
 # Distributed under the terms of the GNU General Public License v2
 
 
-# TODO (in future): could use portage api directly, namely
-#  '/usr/lib/portage/pym/portage/package/ebuild/doebuild.py'
-# instead of using '/usr/bin/ebuild'
-
-import os
-import copy
 import logging
-import subprocess
-
 
-from roverlay import config, util
+import roverlay.portage.manifesthelpers
 
-EBUILD_PROG   = config.get ( 'TOOLS.EBUILD.prog', '/usr/bin/ebuild' )
-EBUILD_TARGET = config.get ( 'TOOLS.EBUILD.target', 'manifest' )
+_MANIFEST_IMPLEMENTATION = \
+	roverlay.portage.manifesthelpers.ExternalManifestCreation
 
-LOGGER = logging.getLogger ( 'ManifestCreation' )
 
-_MANIFEST_ENV = [ None, None ]
+def create_manifest ( package_info, nofail=False ):
+	"""Creates a Manifest for package_info, using the <<best>> implementation
+	available.
 
-def _get_manifest_env ( filter_env=True ):
-	"""Creates an environment suitable for an "ebuild <ebuild> digest|manifest"
-	call (or uses an already existing env).
-	Returns a shallow copy of this env which can then be locally modified
-	(setting DISTDIR).
-	TODO/FIXME: DISTDIR is per repo, so use one env per repo!
+	current implementation: ExternalManifestCreation (using ebuild(1))
 
 	arguments:
-	* filter_env -- if True: start with an empty env and copy vars
-	                         from os.environ selectively
-	                else   : start with os.environ as env
+	* package_info --
+	* nofail -- catch exceptions and return False
 	"""
-
-	mindex = 0 if filter_env else 1
-
-	if _MANIFEST_ENV [mindex] is None:
-		# ((lock this if required))
-
-		if filter_env:
-
-			# selectively import os.environ
-			# FIXME: keep EBUILD_DEFAULT_OPTS?
-			our_env = util.keepenv (
-				( 'PATH', '' ),
-				'LANG',
-				'PWD',
-				'EBUILD_DEFAULT_OPTS'
-			)
+	try:
+		return _MANIFEST_IMPLEMENTATION.do ( package_info )
+	except Exception as e:
+		logging.exception ( e )
+		if nofail:
+			return False
 		else:
-			# copy os.environ
-			our_env = dict ( os.environ )
-
-		# -- common env part
-
-		# set FEATURES
-		# * digest -- needed? (works without it)
-		# * assume-digests --
-		# * unknown-features-warn -- should FEATURES ever change
-		# * noauto -- should prevent ebuild from adding additional actions,
-		#   it still tries to download source packages, which is just wrong here
-		#   'cause it is expected that the R package file exists when calling
-		#   this function, so FETCHCOMMAND/RESUMECOMMAND will be set
-		#   to /bin/true if possible.
-		# * distlocks -- disabled if FETCHCOMMAND/RESUMECOMMAND set to no-op
-		#
-		our_env ['FEATURES'] = \
-			"noauto digest assume-digests unknown-features-warn"
-
-		# try to prevent src fetching
-		for nop in ( '/bin/true', '/bin/echo' ):
-			if os.path.isfile ( nop ):
-				fetch_nop = "%s \${DISTDIR} \${FILE} \${URI}" % nop
-				our_env ['FETCHCOMMAND']  = fetch_nop
-				our_env ['RESUMECOMMAND'] = fetch_nop
-				our_env ['FEATURES']     += " -distlocks"
-				break
-
-		# set PORDIR_OVERLAY
-		our_env ['PORTDIR_OVERLAY'] = config.get_or_fail ( [ 'OVERLAY', 'dir' ] )
-
-		_MANIFEST_ENV [mindex] = our_env
-	# -- end if
-	return copy.copy ( _MANIFEST_ENV [mindex] )
-# --- end of _get_manifest_env (...) ---
-
-def create_manifest ( package_info ):
-
-	my_env = _get_manifest_env ( filter_env=True )
-
-	# using util for reading package info
-	my_env ['DISTDIR']  = util.get_extra_packageinfo (
-		package_info, 'PKG_DISTDIR'
-	)
-
-	ebuild_file = util.get_extra_packageinfo ( package_info, 'EBUILD_FILE' )
-
-	ebuild_call = subprocess.Popen (
-		(
-			EBUILD_PROG,
-			'--debug',
-			ebuild_file,
-			EBUILD_TARGET
-		),
-		stdin=None,
-		stdout=subprocess.PIPE,
-		stderr=subprocess.PIPE,
-		env=my_env
-	)
-
-
-
-	output = ebuild_call.communicate()
-	# necessary? (probably not, FIXME/TODO)
-	ebuild_call.wait()
-
-	# log stdout?
-	#for line in util.pipe_lines ( output [0] ):
-	#	LOGGER.debug ( line )
-
-	# log stderr
-	for line in util.pipe_lines ( output [1], use_filter=True ):
-		LOGGER.warning ( line )
-
-	if ebuild_call.returncode == 0:
-		return True
-	else:
-		LOGGER.error ( "Cannot create Manifest for %s!" % ebuild_file )
-		return False
+			raise
 # --- end of create_manifest (...) ---
-
-def try_manifest ( package_info ):
-	try:
-		return create_manifest ( package_info )
-	except Exception as any_exception:
-		LOGGER.exception ( any_exception )
-		return False
-# --- end of try_manifest (...) ---
-
-t = try_manifest
-
-

diff --git a/roverlay/portage/manifesthelpers.py b/roverlay/portage/manifesthelpers.py
new file mode 100644
index 0000000..f3874d1
--- /dev/null
+++ b/roverlay/portage/manifesthelpers.py
@@ -0,0 +1,207 @@
+# R Overlay -- Manifest creation for ebuilds
+# Copyright 2006-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+
+# TODO (in future): could use portage api directly, namely
+#  '/usr/lib/portage/pym/portage/package/ebuild/doebuild.py'
+# instead of using '/usr/bin/ebuild'
+
+import os
+import copy
+import logging
+import subprocess
+
+
+from roverlay import config, util
+
+
+class ManifestCreation ( object ):
+	"""This is the base class for Manifest file creation."""
+
+	static_instance = None
+
+	def __init__ ( self ):
+		self.logger = logging.getLogger ( 'ManifestCreation' )
+	# --- end of __init__ (...) ---
+
+	def create_for ( self, package_info ):
+		"""Creates a Manifest file for the ebuild of the given package_info."""
+		raise Exception ( "method stub" )
+	# --- end of create_for (...) ---
+
+	@classmethod
+	def do ( cls, package_info ):
+		"""Class/static access to Manifest creation."""
+		if cls.static_instance is None:
+			cls.static_instance = cls()
+
+		return cls.static_instance.create_for ( package_info )
+	# --- end of do (...) ---
+
+
+class ExternalManifestCreation ( ManifestCreation ):
+	"""This class implements Manifest creation using the low level ebuild
+	interface, ebuild(1), which is called in a filtered environment.
+	"""
+
+	def __init__ ( self ):
+		super ( ExternalManifestCreation, self ) . __init__ ()
+		self.manifest_env = ManifestEnv ( filter_env=True )
+		self.ebuild_prog  = config.get ( 'TOOLS.EBUILD.prog', '/usr/bin/ebuild' )
+		# ebuild <ebuild_file> <target>, where target is:
+		self.ebuild_tgt   = config.get ( 'TOOLS.EBUILD.target', 'manifest' )
+	# --- end of __init__ (...) ---
+
+	def create_for ( self, package_info ):
+		"""See ManifestCreation.create_for.
+		Calls ebuild, returns True on success else False.
+
+		raises: *passes Exceptions from failed config lookups
+		"""
+
+
+		my_env = self.manifest_env [ package_info ['origin'] ]
+
+		ebuild_file = util.get_extra_packageinfo ( package_info, 'EBUILD_FILE' )
+
+		ebuild_call = subprocess.Popen (
+			(
+				self.ebuild_prog,
+				ebuild_file,
+				self.ebuild_tgt
+			),
+			stdin=None,
+			stdout=subprocess.PIPE,
+			stderr=subprocess.PIPE,
+			env=my_env
+		)
+
+
+		output = ebuild_call.communicate()
+		# necessary? (probably not, FIXME/TODO)
+		ebuild_call.wait()
+
+		# log stdout?
+		#for line in util.pipe_lines ( output [0] ):
+		#	LOGGER.debug ( line )
+
+		# log stderr
+		for line in util.pipe_lines ( output [1], use_filter=True ):
+			self.logger.warning ( line )
+
+		if ebuild_call.returncode == 0:
+			return True
+		else:
+			self.logger.error ( "Couldn't create Manifest for %s!" % ebuild_file )
+			return False
+	# --- end of create_for (...) ---
+
+
+class ManifestEnv ( object ):
+	"""per-repo environment container for Manifest creation using ebuild."""
+
+	def __init__ ( self, filter_env=True ):
+		"""Initializes a ManifestEnv.
+
+		arguments:
+		* filter_env -- if True: start with an empty env and copy vars
+										 from os.environ selectively
+							 else   : start with os.environ as env
+		"""
+		self.filter_env  = filter_env
+		self._manenv     = dict()
+		self.logger      = logging.getLogger ( 'ManifestEnv' )
+		self._common_env = None
+	# --- end of __init__ (...) ---
+
+	def get_env ( self, repo_name ):
+		"""Returns an env dict for repo_name.
+
+		arguments:
+		* repo_name --
+		"""
+		if not repo_name in self._manenv:
+			repo_env                 = self._get_common_manifest_env()
+			repo_env ['DISTDIR']     = util.get_distdir ( repo_name )
+			self._manenv [repo_name] = repo_env
+
+		return self._manenv [repo_name]
+	# --- end of get_env (...) ---
+
+	# x = ManifestEnv(); env = x [repo] etc.
+	__getitem__ = get_env
+
+	def _get_common_manifest_env ( self, noret=False ):
+		"""Creates an environment suitable for an
+		"ebuild <ebuild> digest|manifest" call (or uses an already existing env).
+		Returns a shallow copy of this env which can then be locally modified
+		(setting DISTDIR).
+
+		arguments:
+		* noret -- do not return copied env if True
+		"""
+
+		if self._common_env is None:
+			# ((lock this if required))
+
+			if self.filter_env:
+
+				# selectively import os.environ
+				# FIXME: keep EBUILD_DEFAULT_OPTS?
+				our_env = util.keepenv (
+					( 'PATH', '' ),
+					'LANG',
+					'PWD',
+					'EBUILD_DEFAULT_OPTS'
+				)
+			else:
+				# copy os.environ
+				our_env = dict ( os.environ )
+
+			# -- common env part
+
+			# set FEATURES
+			# * digest -- needed? (works without it)
+			# * assume-digests --
+			# * unknown-features-warn -- should FEATURES ever change
+			#
+			# * noauto -- should prevent ebuild from adding additional actions,
+			#   it still tries to download source packages, which is just wrong
+			#    here 'cause it is expected that the R package file exists when
+			#   calling this function, so FETCHCOMMAND/RESUMECOMMAND will be set
+			#   to /bin/true if possible.
+			#
+			# * distlocks -- disabled if FETCHCOMMAND/RESUMECOMMAND set to no-op
+			#
+			our_env ['FEATURES'] = \
+				"noauto digest assume-digests unknown-features-warn"
+
+			# try to prevent src fetching
+			for nop in ( '/bin/true', '/bin/echo' ):
+				if os.path.isfile ( nop ):
+					self.logger.debug (
+						'%s disables/replaces FETCHCOMMAND/RESUMECOMMAND' % nop
+					)
+					fetch_nop = "%s \${DISTDIR} \${FILE} \${URI}" % nop
+					our_env ['FETCHCOMMAND']  = fetch_nop
+					our_env ['RESUMECOMMAND'] = fetch_nop
+					our_env ['FEATURES']     += " -distlocks"
+					break
+
+			# set PORDIR_OVERLAY
+			our_env ['PORTDIR_OVERLAY'] = config.get_or_fail (
+				[ 'OVERLAY', 'dir' ]
+			)
+
+			self._common_env = our_env
+		# -- end if
+		if noret:
+			return None
+		else:
+			return copy.copy ( self._common_env )
+	# --- end of _get_common_manifest_env (...) ---
+
+
+
+



             reply	other threads:[~2012-06-15 20:35 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-15 20:34 André Erdmann [this message]
  -- strict thread matches above, loose matches on Subject: below --
2012-06-15 20:34 [gentoo-commits] proj/R_overlay:master commit in: roverlay/portage/ André Erdmann
2012-06-15 20:34 André Erdmann
2012-06-15 20:34 André Erdmann
2012-06-13 16:34 André Erdmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1339754001.2e3c050d5712b079611af4d21b9869817fba05b7.dywi@gentoo \
    --to=dywi@mailerd.de \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox