Gentoo Archives: gentoo-portage-dev

From: Bertrand SIMONNET <bsimonnet@××××××××.org>
To: gentoo-portage-dev@l.g.o
Cc: Bertrand SIMONNET <bsimonnet@××××××××.org>
Subject: [gentoo-portage-dev] [PATCH] package.bashrc: per profile, per-package bashrc mechanism
Date: Tue, 30 Sep 2014 16:45:59
Message-Id: 1412095536-20758-1-git-send-email-bsimonnet@chromium.org
In Reply to: Re: [gentoo-portage-dev] [PATCH 3/3] package.bashrc: per profile, per-package bashrc mechanism by Zac Medico
1 Profiles can define per-package bashrc files to be sourced before emerging.
2 Each line in package.bashrc must be an atom name then a list of space-delimited
3 bashrc files (stored in $profile/bashrc/).
4 ---
5 bin/ebuild.sh | 6 ++--
6 bin/phase-functions.sh | 2 +-
7 bin/save-ebuild-env.sh | 2 +-
8 man/portage.5 | 30 +++++++++++++++++-
9 pym/portage/dbapi/vartree.py | 20 ++++++------
10 .../package/ebuild/_config/special_env_vars.py | 4 +--
11 pym/portage/package/ebuild/config.py | 36 ++++++++++++++++++++++
12 pym/portage/package/ebuild/doebuild.py | 4 ++-
13 pym/portage/repository/config.py | 2 +-
14 9 files changed, 85 insertions(+), 21 deletions(-)
15
16 diff --git a/bin/ebuild.sh b/bin/ebuild.sh
17 index 14cc321..50909e1 100755
18 --- a/bin/ebuild.sh
19 +++ b/bin/ebuild.sh
20 @@ -368,10 +368,10 @@ __source_all_bashrcs() {
21 # source the existing profile.bashrcs.
22 save_IFS
23 IFS=$'\n'
24 - local path_array=($PROFILE_PATHS)
25 + local bashenv_files=($PORTAGE_BASHRC_FILES)
26 restore_IFS
27 - for x in "${path_array[@]}" ; do
28 - [ -f "$x/profile.bashrc" ] && __qa_source "$x/profile.bashrc"
29 + for x in "${bashenv_files[@]}" ; do
30 + __try_source "${x}"
31 done
32 fi
33
34 diff --git a/bin/phase-functions.sh b/bin/phase-functions.sh
35 index f39a024..5dff3bb 100644
36 --- a/bin/phase-functions.sh
37 +++ b/bin/phase-functions.sh
38 @@ -31,7 +31,7 @@ PORTAGE_READONLY_VARS="D EBUILD EBUILD_PHASE EBUILD_PHASE_FUNC \
39 PORTAGE_TMPDIR PORTAGE_UPDATE_ENV PORTAGE_USERNAME \
40 PORTAGE_VERBOSE PORTAGE_WORKDIR_MODE PORTAGE_XATTR_EXCLUDE \
41 PORTDIR \
42 - PROFILE_PATHS REPLACING_VERSIONS REPLACED_BY_VERSION T WORKDIR \
43 + REPLACING_VERSIONS REPLACED_BY_VERSION T WORKDIR \
44 __PORTAGE_HELPER __PORTAGE_TEST_HARDLINK_LOCKS"
45
46 PORTAGE_SAVED_READONLY_VARS="A CATEGORY P PF PN PR PV PVR"
47 diff --git a/bin/save-ebuild-env.sh b/bin/save-ebuild-env.sh
48 index f114c48..1a684b9 100644
49 --- a/bin/save-ebuild-env.sh
50 +++ b/bin/save-ebuild-env.sh
51 @@ -97,7 +97,7 @@ __save_ebuild_env() {
52 GOOD HILITE HOME \
53 LAST_E_CMD LAST_E_LEN LD_PRELOAD MISC_FUNCTIONS_ARGS MOPREFIX \
54 NOCOLOR NORMAL PKGDIR PKGUSE PKG_LOGDIR PKG_TMPDIR \
55 - PORTAGE_BASHRCS_SOURCED PORTAGE_COMPRESS \
56 + PORTAGE_BASHRC_FILES PORTAGE_BASHRCS_SOURCED PORTAGE_COMPRESS \
57 PORTAGE_COMPRESS_EXCLUDE_SUFFIXES \
58 PORTAGE_DOHTML_UNWARNED_SKIPPED_EXTENSIONS \
59 PORTAGE_DOHTML_UNWARNED_SKIPPED_FILES \
60 diff --git a/man/portage.5 b/man/portage.5
61 index e399f0f..309e259 100644
62 --- a/man/portage.5
63 +++ b/man/portage.5
64 @@ -24,6 +24,7 @@ make.defaults
65 packages
66 packages.build
67 package.accept_keywords
68 +package.bashrc
69 package.keywords
70 package.mask
71 package.provided
72 @@ -358,6 +359,31 @@ a '\-'.
73 A list of packages (one per line) that make up a stage1 tarball. Really only
74 useful for stage builders.
75 .TP
76 +.BR package.bashrc
77 +Per-package bashrc mechanism. Contains a list of bashrc files to be sourced
78 +before emerging a given atom. The bashrc files must be stored in bashrc/, in
79 +the profile directory.
80 +
81 +.I Note:
82 +.nf
83 +\- The bashrc files will be sourced after profile.bashrc for the same profile.
84 +\- profile-formats in metadata/layout.conf must contain profile-bashrcs for this
85 +to be enabled.
86 +.fi
87 +
88 +.I Format:
89 +.nf
90 +\- comments begin with # (no inline comments).
91 +\- one atom per line with space-delimited list of bashrc files.
92 +.fi
93 +
94 +.I Example:
95 +.nf
96 +# By setting INSTALL_MASK in bashrc/nostandardconf.conf, we can avoid installing
97 +# the standard configuration and enable another package to install it.
98 +net-misc/dhcp nostardardconf.conf
99 +.fi
100 +.TP
101 .BR package.provided
102 A list of packages (one per line) that portage should assume have been
103 provided. Useful for porting to non-Linux systems. Basically, it's a
104 @@ -1047,11 +1073,13 @@ The default setting for repoman's --echangelog option.
105 The cache formats supported in the metadata tree. There is the old "pms" format
106 and the newer/faster "md5-dict" format. Default is to detect dirs.
107 .TP
108 -.BR profile\-formats " = [pms|portage-1|portage-2]"
109 +.BR profile\-formats " = [pms|portage-1|portage-2|profile-bashrcs]"
110 Control functionality available to profiles in this repo such as which files
111 may be dirs, or the syntax available in parent files. Use "portage-2" if you're
112 unsure. The default is "portage-1-compat" mode which is meant to be compatible
113 with old profiles, but is not allowed to be opted into directly.
114 +Setting profile-bashrcs will enable the per-profile bashrc mechanism
115 +\fBpackage.bashrc\fR.
116 .RE
117 .RE
118
119 diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
120 index 5b947dd..72c15db 100644
121 --- a/pym/portage/dbapi/vartree.py
122 +++ b/pym/portage/dbapi/vartree.py
123 @@ -3663,17 +3663,15 @@ class dblink(object):
124 max_dblnk = dblnk
125 self._installed_instance = max_dblnk
126
127 - if self.settings.get("INSTALL_MASK") or \
128 - "nodoc" in self.settings.features or \
129 - "noinfo" in self.settings.features or \
130 - "noman" in self.settings.features:
131 - # Apply INSTALL_MASK before collision-protect, since it may
132 - # be useful to avoid collisions in some scenarios.
133 - phase = MiscFunctionsProcess(background=False,
134 - commands=["preinst_mask"], phase="preinst",
135 - scheduler=self._scheduler, settings=self.settings)
136 - phase.start()
137 - phase.wait()
138 + # Apply INSTALL_MASK before collision-protect, since it may
139 + # be useful to avoid collisions in some scenarios.
140 + # We cannot detect if this is needed or not here as INSTALL_MASK can be
141 + # modified by bashrc files.
142 + phase = MiscFunctionsProcess(background=False,
143 + commands=["preinst_mask"], phase="preinst",
144 + scheduler=self._scheduler, settings=self.settings)
145 + phase.start()
146 + phase.wait()
147
148 # We check for unicode encoding issues after src_install. However,
149 # the check must be repeated here for binary packages (it's
150 diff --git a/pym/portage/package/ebuild/_config/special_env_vars.py b/pym/portage/package/ebuild/_config/special_env_vars.py
151 index 74fedd6..387f4ae 100644
152 --- a/pym/portage/package/ebuild/_config/special_env_vars.py
153 +++ b/pym/portage/package/ebuild/_config/special_env_vars.py
154 @@ -49,7 +49,7 @@ environ_whitelist += [
155 "FEATURES", "FILESDIR", "HOME", "MERGE_TYPE", "NOCOLOR", "PATH",
156 "PKGDIR",
157 "PKGUSE", "PKG_LOGDIR", "PKG_TMPDIR",
158 - "PORTAGE_ACTUAL_DISTDIR", "PORTAGE_ARCHLIST",
159 + "PORTAGE_ACTUAL_DISTDIR", "PORTAGE_ARCHLIST", "PORTAGE_BASHRC_FILES",
160 "PORTAGE_BASHRC", "PM_EBUILD_HOOK_DIR",
161 "PORTAGE_BINPKG_FILE", "PORTAGE_BINPKG_TAR_OPTS",
162 "PORTAGE_BINPKG_TMPFILE",
163 @@ -74,7 +74,7 @@ environ_whitelist += [
164 "PORTAGE_SIGPIPE_STATUS",
165 "PORTAGE_TMPDIR", "PORTAGE_UPDATE_ENV", "PORTAGE_USERNAME",
166 "PORTAGE_VERBOSE", "PORTAGE_WORKDIR_MODE", "PORTAGE_XATTR_EXCLUDE",
167 - "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH", "PROFILE_PATHS",
168 + "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH",
169 "REPLACING_VERSIONS", "REPLACED_BY_VERSION",
170 "ROOT", "ROOTPATH", "T", "TMP", "TMPDIR",
171 "USE_EXPAND", "USE_ORDER", "WORKDIR",
172 diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py
173 index f639e14..183627f 100644
174 --- a/pym/portage/package/ebuild/config.py
175 +++ b/pym/portage/package/ebuild/config.py
176 @@ -316,6 +316,7 @@ class config(object):
177 self._accept_restrict = copy.deepcopy(clone._accept_restrict)
178 self._paccept_restrict = copy.deepcopy(clone._paccept_restrict)
179 self._penvdict = copy.deepcopy(clone._penvdict)
180 + self._pbashrcdict = copy.deepcopy(clone._pbashrcdict)
181 self._expand_map = copy.deepcopy(clone._expand_map)
182
183 else:
184 @@ -661,6 +662,7 @@ class config(object):
185 self._ppropertiesdict = portage.dep.ExtendedAtomDict(dict)
186 self._paccept_restrict = portage.dep.ExtendedAtomDict(dict)
187 self._penvdict = portage.dep.ExtendedAtomDict(dict)
188 + self._pbashrcdict = {}
189
190 self._repo_make_defaults = {}
191 for repo in self.repositories.repos_with_profiles():
192 @@ -742,6 +744,25 @@ class config(object):
193 for k, v in penvdict.items():
194 self._penvdict.setdefault(k.cp, {})[k] = v
195
196 + # package.bashrc
197 + for profile in profiles_complex:
198 + if not 'profile-bashrcs' in profile.profile_formats:
199 + continue
200 + self._pbashrcdict[profile] = \
201 + portage.dep.ExtendedAtomDict(dict)
202 + bashrc = grabdict_package(os.path.join(profile.location,
203 + "package.bashrc"), recursive=1, allow_wildcard=True,
204 + allow_repo=True, verify_eapi=False)
205 + if not bashrc:
206 + continue
207 +
208 + for k, v in bashrc.items():
209 + envfiles = [os.path.join(profile.location,
210 + "bashrc",
211 + envname) for envname in v]
212 + self._pbashrcdict[profile].setdefault(k.cp, {})\
213 + .setdefault(k, []).extend(envfiles)
214 +
215 #getting categories from an external file now
216 self.categories = [grabfile(os.path.join(x, "categories")) \
217 for x in locations_manager.profile_and_user_locations]
218 @@ -1501,6 +1522,21 @@ class config(object):
219 for x in penv_matches:
220 self._penv.extend(x)
221
222 + bashrc_files = []
223 +
224 + for profile in self._locations_manager.profiles_complex:
225 + bashrc_files.append(os.path.join(profile.location,
226 + 'profile.bashrc'))
227 + if profile in self._pbashrcdict:
228 + cpdict = self._pbashrcdict[profile].get(cp)
229 + if cpdict:
230 + bashrc_matches = \
231 + ordered_by_atom_specificity(cpdict, cpv_slot)
232 + for x in bashrc_matches:
233 + bashrc_files.extend(x)
234 +
235 + self.configdict["BASHRC_FILES"] = bashrc_files
236 +
237 protected_pkg_keys = set(pkg_configdict)
238 protected_pkg_keys.discard('USE')
239
240 diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
241 index 01707ae..5224775 100644
242 --- a/pym/portage/package/ebuild/doebuild.py
243 +++ b/pym/portage/package/ebuild/doebuild.py
244 @@ -335,7 +335,9 @@ def doebuild_environment(myebuild, mydo, myroot=None, settings=None,
245 mysettings["ECLASSDIR"] = mysettings["PORTDIR"]+"/eclass"
246 mysettings["SANDBOX_LOG"] = mycpv.replace("/", "_-_")
247
248 - mysettings["PROFILE_PATHS"] = "\n".join(mysettings.profiles)
249 + mysettings["PORTAGE_BASHRC_FILES"] = \
250 + "\n".join(mysettings.configdict["BASHRC_FILES"])
251 +
252 mysettings["P"] = mysplit[0]+"-"+mysplit[1]
253 mysettings["PN"] = mysplit[0]
254 mysettings["PV"] = mysplit[1]
255 diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py
256 index 5e0d055..bef643d 100644
257 --- a/pym/portage/repository/config.py
258 +++ b/pym/portage/repository/config.py
259 @@ -40,7 +40,7 @@ if sys.hexversion >= 0x3000000:
260 _invalid_path_char_re = re.compile(r'[^a-zA-Z0-9._\-+:/]')
261
262 _valid_profile_formats = frozenset(
263 - ['pms', 'portage-1', 'portage-2'])
264 + ['pms', 'portage-1', 'portage-2', 'profile-bashrcs'])
265
266 _portage1_profiles_allow_directories = frozenset(
267 ["portage-1-compat", "portage-1", 'portage-2'])
268 --
269 2.1.0.rc2.206.gedb03e5