public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-portage-dev] [PATCH] per package environment: generalize the mechanism to be profile specific
@ 2014-09-11 11:18 Bertrand Simonnet
  2014-09-11 19:49 ` Zac Medico
  0 siblings, 1 reply; 48+ messages in thread
From: Bertrand Simonnet @ 2014-09-11 11:18 UTC (permalink / raw
  To: gentoo-portage-dev


[-- Attachment #1.1: Type: text/plain, Size: 1152 bytes --]

Hi guys,

I have been working on a patch to make package.env (and env/ files)
stackable with the profiles.
The main goal would be to have a mechanism to be able to define a
per-package, per-profile environment in a simple way.

We can currently do this with profile.bashrc but we have to add some logic
there to decide which package are relevant which already exist in ebuild.sh
and pym/*.

I attached my current patch which contain two main modifications:
- ebuild.sh walk the profile and source all scripts with path:
${profile_path}/env/${category}/${PN}
- config.py imports package.env from all profiles and then from
/etc/portage/package.env

Note:
* I gated the env/$CATEGORY/$PN scripts with a new feature: per-profile-env.
   I couldn't do this with package.env as the scripts are parsed before we
initialize self.features.
* I am not particularly attach to both package.env and env/$CATEGORY/$PN.
It might make more sense to have only env/$CATEGORY/$PN, especially
considering the problem with package.env.

Do you have any suggestions on this patch ?

Would you be willing to accept this patch once the few problems are sorted
out ?

Thanks!

[-- Attachment #1.2: Type: text/html, Size: 2513 bytes --]

[-- Attachment #2: 0001-per-profile-package-env.patch --]
[-- Type: application/octet-stream, Size: 8587 bytes --]

From 550d25fc93d087186438bbbf1cc7aacbfd6bbc8f Mon Sep 17 00:00:00 2001
From: Bertrand SIMONNET <bsimonnet@chromium.org>
Date: Tue, 29 Jul 2014 15:14:40 -0700
Subject: [PATCH] Make package.env and env profile specific

Allows profiles to override environment variables throught package.env and env.
package.env becomes a per-profile configuration like package.use and
package.mask.

The environment bash file invoked by package.env must me placed in the same
profile.

Change-Id: I16bcd75790213d2204f83d4aa6e8b910f8829b6e
---
 bin/ebuild.sh                        | 78 ++++++++++++++++++++++--------------
 pym/portage/const.py                 |  1 +
 pym/portage/package/ebuild/config.py | 55 ++++++++++++++-----------
 3 files changed, 80 insertions(+), 54 deletions(-)

diff --git a/bin/ebuild.sh b/bin/ebuild.sh
index be044e0..e188df7 100755
--- a/bin/ebuild.sh
+++ b/bin/ebuild.sh
@@ -67,11 +67,11 @@ unset BASH_ENV
 # earlier portage versions do not detect a version change in this case
 # (9999 to 9999) and therefore they try execute an incompatible version of
 # ebuild.sh during the upgrade.
-export PORTAGE_BZIP2_COMMAND=${PORTAGE_BZIP2_COMMAND:-bzip2} 
+export PORTAGE_BZIP2_COMMAND=${PORTAGE_BZIP2_COMMAND:-bzip2}
 
 # These two functions wrap sourcing and calling respectively.  At present they
 # perform a qa check to make sure eclasses and ebuilds and profiles don't mess
-# with shell opts (shopts).  Ebuilds/eclasses changing shopts should reset them 
+# with shell opts (shopts).  Ebuilds/eclasses changing shopts should reset them
 # when they are done.
 
 __qa_source() {
@@ -275,7 +275,7 @@ inherit() {
 		set +f
 
 		__qa_source "$location" || die "died sourcing $location in inherit()"
-		
+
 		#turn off glob expansion
 		set -f
 
@@ -290,7 +290,7 @@ inherit() {
 
 		[ "${B_IUSE+set}"     = set ] && IUSE="${B_IUSE}"
 		[ "${B_IUSE+set}"     = set ] || unset IUSE
-		
+
 		[ "${B_REQUIRED_USE+set}"     = set ] && REQUIRED_USE="${B_REQUIRED_USE}"
 		[ "${B_REQUIRED_USE+set}"     = set ] || unset REQUIRED_USE
 
@@ -372,42 +372,60 @@ __source_all_bashrcs() {
 		restore_IFS
 		for x in "${path_array[@]}" ; do
 			[ -f "$x/profile.bashrc" ] && __qa_source "$x/profile.bashrc"
+			[[ " ${FEATURES} " == *" per-profile-env "* ]] && \
+				__source_env_files "$x/env"
 		done
 	fi
 
-	if [ -r "${PORTAGE_BASHRC}" ] ; then
-		if [ "$PORTAGE_DEBUG" != "1" ] || [ "${-/x/}" != "$-" ]; then
-			source "${PORTAGE_BASHRC}"
-		else
-			set -x
-			source "${PORTAGE_BASHRC}"
-			set +x
-		fi
-	fi
+	# The user's bashrc is the ONLY non-portage bit of code
+	# that can change shopts without a QA violation.
+	__try_source "${PORTAGE_BASHRC}" "no_qa"
 
 	if [[ $EBUILD_PHASE != depend ]] ; then
-		# The user's bashrc is the ONLY non-portage bit of code that can
-		# change shopts without a QA violation.
-		for x in "${PM_EBUILD_HOOK_DIR}"/${CATEGORY}/{${PN},${PN}:${SLOT%/*},${P},${PF}}; do
-			if [ -r "${x}" ]; then
-				# If $- contains x, then tracing has already been enabled
-				# elsewhere for some reason. We preserve it's state so as
-				# not to interfere.
-				if [ "$PORTAGE_DEBUG" != "1" ] || [ "${-/x/}" != "$-" ]; then
-					source "${x}"
-				else
-					set -x
-					source "${x}"
-					set +x
-				fi
-			fi
-		done
+		__source_env_files "${PM_EBUILD_HOOK_DIR}" "no_qa"
 	fi
 
 	[ ! -z "${OCC}" ] && export CC="${OCC}"
 	[ ! -z "${OCXX}" ] && export CXX="${OCXX}"
 }
 
+# @FUNCTION: __source_env_files
+# @DESCRIPTION:
+# Source the files relevant to the current package from the given path.
+# If $2 is not 'no_qa', all the scripts are sourced with __qa_source.
+__source_env_files() {
+	for x in "${1}"/${CATEGORY}/{${PN},${PN}:${SLOT%/*},${P},${PF}}; do
+		__try_source "${x}" "${2}"
+	done
+}
+
+# @FUNCTION: __try_source
+# @DESCRIPTION:
+# If the path given as argument exists, source the file while preserving
+# $-.
+# If $2 is not 'no_qa', the file is sourced with __qa_source.
+__try_source() {
+	if [[ -r "$1" ]]; then
+		# If $- contains x, then tracing has already been enabled
+		# elsewhere for some reason. We preserve it's state so as
+		# not to interfere.
+		if [[ "$PORTAGE_DEBUG" != "1" ]] || [[ "${-/x/}" != "$-" ]]; then
+			if [[ "${2}" == "no_qa" ]]; then
+				source "${x}"
+			else
+				__qa_source "${x}"
+			fi
+		else
+			set -x
+			if [[ "${2}" == "no_qa" ]]; then
+				source "${x}"
+			else
+				__qa_source "${x}"
+			fi
+			set +x
+		fi
+	fi
+}
 # === === === === === === === === === === === === === === === === === ===
 # === === === === === functions end, main part begins === === === === ===
 # === === === === === === === === === === === === === === === === === ===
@@ -572,7 +590,7 @@ if ! has "$EBUILD_PHASE" clean cleanrm ; then
 		PDEPEND+="${PDEPEND:+ }${E_PDEPEND}"
 		HDEPEND+="${HDEPEND:+ }${E_HDEPEND}"
 		REQUIRED_USE+="${REQUIRED_USE:+ }${E_REQUIRED_USE}"
-		
+
 		unset ECLASS E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND E_HDEPEND \
 			__INHERITED_QA_CACHE
 
diff --git a/pym/portage/const.py b/pym/portage/const.py
index aab6e8a..3043656 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -166,6 +166,7 @@ SUPPORTED_FEATURES       = frozenset([
 	"notitles",
 	"parallel-fetch",
 	"parallel-install",
+	"per-profile-env",
 	"prelink-checksums",
 	"preserve-libs",
 	"protect-owned",
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py
index f639e14..6c695fe 100644
--- a/pym/portage/package/ebuild/config.py
+++ b/pym/portage/package/ebuild/config.py
@@ -719,28 +719,38 @@ class config(object):
 					self._paccept_restrict.setdefault(k.cp, {})[k] = v
 
 				#package.env
-				penvdict = grabdict_package(os.path.join(
-					abs_user_config, "package.env"), recursive=1, allow_wildcard=True, \
-					allow_repo=True, verify_eapi=False)
-				v = penvdict.pop("*/*", None)
-				if v is not None:
-					global_wildcard_conf = {}
-					self._grab_pkg_env(v, global_wildcard_conf)
-					incrementals = self.incrementals
-					conf_configdict = self.configdict["conf"]
-					for k, v in global_wildcard_conf.items():
-						if k in incrementals:
-							if k in conf_configdict:
-								conf_configdict[k] = \
-									conf_configdict[k] + " " + v
+				envlocations = [v.location for v in profiles_complex]
+				envlocations.append(os.path.join(self['PORTAGE_CONFIGROOT'], USER_CONFIG_PATH))
+				penvdicts = [(grabdict_package(os.path.join(x, "package.env"),
+								recursive=1, allow_wildcard=True,
+								allow_repo=True, verify_eapi=False), x) \
+				 for x in envlocations]
+
+				for (penvdict, location) in penvdicts:
+					v = penvdict.pop("*/*", None)
+					if v is not None:
+						global_wildcard_conf = {}
+						v = [os.path.join(location, 'env', envname) \
+							for envname in v]
+						self._grab_pkg_env(v, global_wildcard_conf)
+						incrementals = self.incrementals
+						conf_configdict = self.configdict["conf"]
+						for k, v in global_wildcard_conf.items():
+							if k in incrementals:
+								if k in conf_configdict:
+									conf_configdict[k] = \
+										conf_configdict[k] + " " + v
+								else:
+									conf_configdict[k] = v
 							else:
 								conf_configdict[k] = v
-						else:
-							conf_configdict[k] = v
-						expand_map[k] = v
+								expand_map[k] = v
 
-				for k, v in penvdict.items():
-					self._penvdict.setdefault(k.cp, {})[k] = v
+					for k, v in penvdict.items():
+						penvfiles = [os.path.join(location, 'env', envname) \
+							for envname in v]
+						self._penvdict.setdefault(k.cp, {})\
+							.setdefault(k, []).extend(penvfiles)
 
 			#getting categories from an external file now
 			self.categories = [grabfile(os.path.join(x, "categories")) \
@@ -1692,18 +1702,15 @@ class config(object):
 		# setcpv triggers lazy instantiation of things like _use_manager.
 		_eapi_cache.clear()
 
-	def _grab_pkg_env(self, penv, container, protected_keys=None):
+	def _grab_pkg_env(self, penvfiles, container, protected_keys=None):
 		if protected_keys is None:
 			protected_keys = ()
-		abs_user_config = os.path.join(
-			self['PORTAGE_CONFIGROOT'], USER_CONFIG_PATH)
 		non_user_variables = self._non_user_variables
 		# Make a copy since we don't want per-package settings
 		# to pollute the global expand_map.
 		expand_map = self._expand_map.copy()
 		incrementals = self.incrementals
-		for envname in penv:
-			penvfile = os.path.join(abs_user_config, "env", envname)
+		for penvfile in penvfiles:
 			penvconfig = getconfig(penvfile, tolerant=self._tolerant,
 				allow_sourcing=True, expand=expand_map)
 			if penvconfig is None:
-- 
2.1.0.rc2.206.gedb03e5


^ permalink raw reply related	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2014-10-24 22:41 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-11 11:18 [gentoo-portage-dev] [PATCH] per package environment: generalize the mechanism to be profile specific Bertrand Simonnet
2014-09-11 19:49 ` Zac Medico
2014-09-15 18:42   ` Bertrand Simonnet
2014-09-15 20:40     ` Zac Medico
2014-09-16 18:17       ` Bertrand Simonnet
2014-09-16 19:17         ` Zac Medico
2014-09-16 21:37           ` Bertrand Simonnet
2014-09-16 22:13             ` Zac Medico
2014-09-17  7:14               ` Alexander Berntsen
2014-09-17 18:02                 ` Zac Medico
2014-09-17 18:12                   ` Bertrand Simonnet
2014-09-17 20:36                     ` Zac Medico
2014-09-17 21:28             ` Michał Górny
2014-09-17 21:43               ` Zac Medico
2014-09-17 21:57                 ` Bertrand Simonnet
2014-09-17 23:46                   ` Bertrand Simonnet
2014-09-18  7:40                     ` Alexander Berntsen
2014-09-18  8:02                   ` Michał Górny
2014-09-18 17:54                     ` Bertrand Simonnet
2014-09-22 16:16                       ` Bertrand Simonnet
2014-09-22 18:16                         ` Zac Medico
2014-09-22 18:24                           ` Zac Medico
2014-09-22 18:43                             ` Bertrand Simonnet
2014-09-23  0:48                               ` Zac Medico
2014-09-23  0:57                                 ` Bertrand Simonnet
2014-09-24 16:05                                   ` Zac Medico
2014-09-26 16:22                                   ` Michał Górny
2014-09-26 16:28                                     ` Zac Medico
2014-09-29 22:31                                       ` Bertrand SIMONNET
2014-09-29 22:31                                         ` [gentoo-portage-dev] [PATCH 1/3] Refactor bashrc scripts sourcing Bertrand SIMONNET
2014-09-29 22:31                                           ` [gentoo-portage-dev] [PATCH 2/3] Add profile-formats to profile_complex Bertrand SIMONNET
2014-09-29 22:31                                             ` [gentoo-portage-dev] [PATCH 3/3] package.bashrc: per profile, per-package bashrc mechanism Bertrand SIMONNET
2014-09-30 22:16                                               ` [gentoo-portage-dev] " Bertrand Simonnet
2014-10-06 17:38                                                 ` Bertrand Simonnet
2014-10-06 18:57                                                   ` Zac Medico
2014-10-06 21:01                                                     ` Brian Dolbec
2014-10-07  0:15                                                       ` Bertrand Simonnet
2014-10-24  2:00                                                       ` Zac Medico
2014-10-24  7:25                                                         ` Alexander Berntsen
2014-10-24 20:57                                                           ` Zac Medico
2014-10-24 22:41                                                             ` Alexander Berntsen
2014-09-30  0:12                                       ` [gentoo-portage-dev] [PATCH] per package environment: generalize the mechanism to be profile specific Bertrand SIMONNET
2014-09-30  0:12                                         ` [gentoo-portage-dev] [PATCH 1/3] Refactor bashrc scripts sourcing Bertrand SIMONNET
2014-09-30  0:12                                           ` [gentoo-portage-dev] [PATCH 2/3] Add profile-formats to profile_complex Bertrand SIMONNET
2014-09-30  0:12                                             ` [gentoo-portage-dev] [PATCH 3/3] package.bashrc: per profile, per-package bashrc mechanism Bertrand SIMONNET
2014-09-30 15:19                                               ` Zac Medico
2014-09-30 16:45                                                 ` [gentoo-portage-dev] [PATCH] " Bertrand SIMONNET
2014-09-30 15:21                                         ` [gentoo-portage-dev] [PATCH] per package environment: generalize the mechanism to be profile specific Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox