package.bashrc: per profile, per-package bashrc mechanism
Profiles can define per-package bashrc files to be sourced before emerging.
Each line in package.bashrc must be an atom name then a list of space-delimited
bashrc files (stored in $profile/bashrc/).
(cherry picked from commit 803dafc462027d6015721f40513abb5f57dc1178)
Change-Id: Iae234b08d14fa63cdb3d973c2fb85430e88bf3f0
Reviewed-on: https://chromium-review.googlesource.com/225513
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Tested-by: Bertrand Simonnet <bsimonnet@chromium.org>
diff --git a/bin/ebuild.sh b/bin/ebuild.sh
index 14cc321..50909e1 100755
--- a/bin/ebuild.sh
+++ b/bin/ebuild.sh
@@ -368,10 +368,10 @@
# source the existing profile.bashrcs.
save_IFS
IFS=$'\n'
- local path_array=($PROFILE_PATHS)
+ local bashenv_files=($PORTAGE_BASHRC_FILES)
restore_IFS
- for x in "${path_array[@]}" ; do
- [ -f "$x/profile.bashrc" ] && __qa_source "$x/profile.bashrc"
+ for x in "${bashenv_files[@]}" ; do
+ __try_source "${x}"
done
fi
diff --git a/bin/phase-functions.sh b/bin/phase-functions.sh
index f39a024..5dff3bb 100644
--- a/bin/phase-functions.sh
+++ b/bin/phase-functions.sh
@@ -31,7 +31,7 @@
PORTAGE_TMPDIR PORTAGE_UPDATE_ENV PORTAGE_USERNAME \
PORTAGE_VERBOSE PORTAGE_WORKDIR_MODE PORTAGE_XATTR_EXCLUDE \
PORTDIR \
- PROFILE_PATHS REPLACING_VERSIONS REPLACED_BY_VERSION T WORKDIR \
+ REPLACING_VERSIONS REPLACED_BY_VERSION T WORKDIR \
__PORTAGE_HELPER __PORTAGE_TEST_HARDLINK_LOCKS"
PORTAGE_SAVED_READONLY_VARS="A CATEGORY P PF PN PR PV PVR"
diff --git a/bin/save-ebuild-env.sh b/bin/save-ebuild-env.sh
index c776f79..8b32bc4 100644
--- a/bin/save-ebuild-env.sh
+++ b/bin/save-ebuild-env.sh
@@ -97,7 +97,7 @@
GOOD HILITE HOME \
LAST_E_CMD LAST_E_LEN LD_PRELOAD MISC_FUNCTIONS_ARGS MOPREFIX \
NOCOLOR NORMAL PKGDIR PKGUSE PKG_LOGDIR PKG_TMPDIR \
- PORTAGE_BASHRCS_SOURCED PORTAGE_COMPRESS \
+ PORTAGE_BASHRC_FILES PORTAGE_BASHRCS_SOURCED PORTAGE_COMPRESS \
PORTAGE_COMPRESS_EXCLUDE_SUFFIXES \
PORTAGE_DOHTML_UNWARNED_SKIPPED_EXTENSIONS \
PORTAGE_DOHTML_UNWARNED_SKIPPED_FILES \
diff --git a/man/portage.5 b/man/portage.5
index e399f0f..309e259 100644
--- a/man/portage.5
+++ b/man/portage.5
@@ -24,6 +24,7 @@
packages
packages.build
package.accept_keywords
+package.bashrc
package.keywords
package.mask
package.provided
@@ -358,6 +359,31 @@
A list of packages (one per line) that make up a stage1 tarball. Really only
useful for stage builders.
.TP
+.BR package.bashrc
+Per-package bashrc mechanism. Contains a list of bashrc files to be sourced
+before emerging a given atom. The bashrc files must be stored in bashrc/, in
+the profile directory.
+
+.I Note:
+.nf
+\- The bashrc files will be sourced after profile.bashrc for the same profile.
+\- profile-formats in metadata/layout.conf must contain profile-bashrcs for this
+to be enabled.
+.fi
+
+.I Format:
+.nf
+\- comments begin with # (no inline comments).
+\- one atom per line with space-delimited list of bashrc files.
+.fi
+
+.I Example:
+.nf
+# By setting INSTALL_MASK in bashrc/nostandardconf.conf, we can avoid installing
+# the standard configuration and enable another package to install it.
+net-misc/dhcp nostardardconf.conf
+.fi
+.TP
.BR package.provided
A list of packages (one per line) that portage should assume have been
provided. Useful for porting to non-Linux systems. Basically, it's a
@@ -1047,11 +1073,13 @@
The cache formats supported in the metadata tree. There is the old "pms" format
and the newer/faster "md5-dict" format. Default is to detect dirs.
.TP
-.BR profile\-formats " = [pms|portage-1|portage-2]"
+.BR profile\-formats " = [pms|portage-1|portage-2|profile-bashrcs]"
Control functionality available to profiles in this repo such as which files
may be dirs, or the syntax available in parent files. Use "portage-2" if you're
unsure. The default is "portage-1-compat" mode which is meant to be compatible
with old profiles, but is not allowed to be opted into directly.
+Setting profile-bashrcs will enable the per-profile bashrc mechanism
+\fBpackage.bashrc\fR.
.RE
.RE
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 0222ae5..7b49b70 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -3664,17 +3664,15 @@
max_dblnk = dblnk
self._installed_instance = max_dblnk
- if self.settings.get("INSTALL_MASK") or \
- "nodoc" in self.settings.features or \
- "noinfo" in self.settings.features or \
- "noman" in self.settings.features:
- # Apply INSTALL_MASK before collision-protect, since it may
- # be useful to avoid collisions in some scenarios.
- phase = MiscFunctionsProcess(background=False,
- commands=["preinst_mask"], phase="preinst",
- scheduler=self._scheduler, settings=self.settings)
- phase.start()
- phase.wait()
+ # Apply INSTALL_MASK before collision-protect, since it may
+ # be useful to avoid collisions in some scenarios.
+ # We cannot detect if this is needed or not here as INSTALL_MASK can be
+ # modified by bashrc files.
+ phase = MiscFunctionsProcess(background=False,
+ commands=["preinst_mask"], phase="preinst",
+ scheduler=self._scheduler, settings=self.settings)
+ phase.start()
+ phase.wait()
# We check for unicode encoding issues after src_install. However,
# the check must be repeated here for binary packages (it's
diff --git a/pym/portage/package/ebuild/_config/special_env_vars.py b/pym/portage/package/ebuild/_config/special_env_vars.py
index 06f3484..8803491 100644
--- a/pym/portage/package/ebuild/_config/special_env_vars.py
+++ b/pym/portage/package/ebuild/_config/special_env_vars.py
@@ -49,7 +49,7 @@
"FEATURES", "FILESDIR", "HOME", "MERGE_TYPE", "NOCOLOR", "PATH",
"PKGDIR",
"PKGUSE", "PKG_LOGDIR", "PKG_TMPDIR",
- "PORTAGE_ACTUAL_DISTDIR", "PORTAGE_ARCHLIST",
+ "PORTAGE_ACTUAL_DISTDIR", "PORTAGE_ARCHLIST", "PORTAGE_BASHRC_FILES",
"PORTAGE_BASHRC", "PM_EBUILD_HOOK_DIR",
"PORTAGE_BINPKG_FILE", "PORTAGE_BINPKG_TAR_OPTS",
"PORTAGE_BINPKG_TMPFILE",
@@ -74,7 +74,7 @@
"PORTAGE_SIGPIPE_STATUS",
"PORTAGE_TMPDIR", "PORTAGE_UPDATE_ENV", "PORTAGE_USERNAME",
"PORTAGE_VERBOSE", "PORTAGE_WORKDIR_MODE", "PORTAGE_XATTR_EXCLUDE",
- "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH", "PROFILE_PATHS",
+ "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH",
"REPLACING_VERSIONS", "REPLACED_BY_VERSION",
"ROOT", "ROOTPATH", "SYSROOT", "T", "TMP", "TMPDIR",
"USE_EXPAND", "USE_ORDER", "WORKDIR",
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py
index f639e14..5ede061 100644
--- a/pym/portage/package/ebuild/config.py
+++ b/pym/portage/package/ebuild/config.py
@@ -254,6 +254,7 @@
self._iuse_implicit_match = clone._iuse_implicit_match
self._non_user_variables = clone._non_user_variables
self._env_d_blacklist = clone._env_d_blacklist
+ self._pbashrc = clone._pbashrc
self._repo_make_defaults = clone._repo_make_defaults
self.usemask = clone.usemask
self.useforce = clone.useforce
@@ -316,6 +317,7 @@
self._accept_restrict = copy.deepcopy(clone._accept_restrict)
self._paccept_restrict = copy.deepcopy(clone._paccept_restrict)
self._penvdict = copy.deepcopy(clone._penvdict)
+ self._pbashrcdict = copy.deepcopy(clone._pbashrcdict)
self._expand_map = copy.deepcopy(clone._expand_map)
else:
@@ -661,6 +663,8 @@
self._ppropertiesdict = portage.dep.ExtendedAtomDict(dict)
self._paccept_restrict = portage.dep.ExtendedAtomDict(dict)
self._penvdict = portage.dep.ExtendedAtomDict(dict)
+ self._pbashrcdict = {}
+ self._pbashrc = ()
self._repo_make_defaults = {}
for repo in self.repositories.repos_with_profiles():
@@ -742,6 +746,25 @@
for k, v in penvdict.items():
self._penvdict.setdefault(k.cp, {})[k] = v
+ # package.bashrc
+ for profile in profiles_complex:
+ if not 'profile-bashrcs' in profile.profile_formats:
+ continue
+ self._pbashrcdict[profile] = \
+ portage.dep.ExtendedAtomDict(dict)
+ bashrc = grabdict_package(os.path.join(profile.location,
+ "package.bashrc"), recursive=1, allow_wildcard=True,
+ allow_repo=True, verify_eapi=False)
+ if not bashrc:
+ continue
+
+ for k, v in bashrc.items():
+ envfiles = [os.path.join(profile.location,
+ "bashrc",
+ envname) for envname in v]
+ self._pbashrcdict[profile].setdefault(k.cp, {})\
+ .setdefault(k, []).extend(envfiles)
+
#getting categories from an external file now
self.categories = [grabfile(os.path.join(x, "categories")) \
for x in locations_manager.profile_and_user_locations]
@@ -1501,6 +1524,23 @@
for x in penv_matches:
self._penv.extend(x)
+ bashrc_files = []
+
+ for profile in self._locations_manager.profiles_complex:
+ profile_bashrc = os.path.join(profile.location,
+ 'profile.bashrc')
+ if os.path.exists(profile_bashrc):
+ bashrc_files.append(profile_bashrc)
+ if profile in self._pbashrcdict:
+ cpdict = self._pbashrcdict[profile].get(cp)
+ if cpdict:
+ bashrc_matches = \
+ ordered_by_atom_specificity(cpdict, cpv_slot)
+ for x in bashrc_matches:
+ bashrc_files.extend(x)
+
+ self._pbashrc = tuple(bashrc_files)
+
protected_pkg_keys = set(pkg_configdict)
protected_pkg_keys.discard('USE')
diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
index c642c67..98e5903 100644
--- a/pym/portage/package/ebuild/doebuild.py
+++ b/pym/portage/package/ebuild/doebuild.py
@@ -336,7 +336,8 @@
mysettings["ECLASSDIR"] = mysettings["PORTDIR"]+"/eclass"
mysettings["SANDBOX_LOG"] = mycpv.replace("/", "_-_")
- mysettings["PROFILE_PATHS"] = "\n".join(mysettings.profiles)
+ mysettings["PORTAGE_BASHRC_FILES"] = "\n".join(mysettings._pbashrc)
+
mysettings["P"] = mysplit[0]+"-"+mysplit[1]
mysettings["PN"] = mysplit[0]
mysettings["PV"] = mysplit[1]
diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py
index 24c3112..a3144b1 100644
--- a/pym/portage/repository/config.py
+++ b/pym/portage/repository/config.py
@@ -40,7 +40,7 @@
_invalid_path_char_re = re.compile(r'[^a-zA-Z0-9._\-+:/]')
_valid_profile_formats = frozenset(
- ['pms', 'portage-1', 'portage-2'])
+ ['pms', 'portage-1', 'portage-2', 'profile-bashrcs'])
_portage1_profiles_allow_directories = frozenset(
["portage-1-compat", "portage-1", 'portage-2'])