1 |
commit: 33380ad5e121a47375442de08fd9239b9102b1fa |
2 |
Author: Michał Górny <mgorny <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sat Dec 12 22:06:33 2015 +0000 |
4 |
Commit: Michał Górny <mgorny <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Dec 22 22:12:23 2015 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=33380ad5 |
7 |
|
8 |
python*-r1.eclass: Commonize PYTHON_COMPAT processing, cache the result |
9 |
|
10 |
Introduce a common _python_set_impls function in python-utils-r1.eclass |
11 |
that validates and processes PYTHON_COMPAT, then stores the result in |
12 |
_PYTHON_SUPPORTED_IMPLS and _PYTHON_UNSUPPORTED_IMPLS variables. Reuse |
13 |
those variables in all python-r1 suite eclasses, effectively reducing |
14 |
code duplication and providing cache for repeated implementation support |
15 |
checks. |
16 |
|
17 |
eclass/python-any-r1.eclass | 28 +++++-------------- |
18 |
eclass/python-r1.eclass | 47 ++++++++------------------------ |
19 |
eclass/python-single-r1.eclass | 61 ++++++++++++------------------------------ |
20 |
eclass/python-utils-r1.eclass | 49 +++++++++++++++++++++++++++++++++ |
21 |
4 files changed, 83 insertions(+), 102 deletions(-) |
22 |
|
23 |
diff --git a/eclass/python-any-r1.eclass b/eclass/python-any-r1.eclass |
24 |
index 721ba45..dbfeded 100644 |
25 |
--- a/eclass/python-any-r1.eclass |
26 |
+++ b/eclass/python-any-r1.eclass |
27 |
@@ -71,12 +71,6 @@ if [[ ! ${_PYTHON_ANY_R1} ]]; then |
28 |
# @CODE |
29 |
# PYTHON_COMPAT=( python{2_5,2_6,2_7} ) |
30 |
# @CODE |
31 |
-if ! declare -p PYTHON_COMPAT &>/dev/null; then |
32 |
- die 'PYTHON_COMPAT not declared.' |
33 |
-fi |
34 |
-if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then |
35 |
- die 'PYTHON_COMPAT must be an array.' |
36 |
-fi |
37 |
|
38 |
# @ECLASS-VARIABLE: PYTHON_REQ_USE |
39 |
# @DEFAULT_UNSET |
40 |
@@ -119,16 +113,10 @@ _python_any_set_globals() { |
41 |
local usestr i PYTHON_PKG_DEP |
42 |
[[ ${PYTHON_REQ_USE} ]] && usestr="[${PYTHON_REQ_USE}]" |
43 |
|
44 |
- # check for invalid PYTHON_COMPAT |
45 |
- for i in "${PYTHON_COMPAT[@]}"; do |
46 |
- # the function simply dies on invalid impl |
47 |
- _python_impl_supported "${i}" |
48 |
- done |
49 |
+ _python_set_impls |
50 |
|
51 |
PYTHON_DEPS= |
52 |
- for i in "${_PYTHON_ALL_IMPLS[@]}"; do |
53 |
- has "${i}" "${PYTHON_COMPAT[@]}" || continue |
54 |
- |
55 |
+ for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
56 |
python_export "${i}" PYTHON_PKG_DEP |
57 |
|
58 |
PYTHON_DEPS="${PYTHON_PKG_DEP} ${PYTHON_DEPS}" |
59 |
@@ -209,9 +197,7 @@ python_gen_any_dep() { |
60 |
[[ ${depstr} ]] || die "No dependency string provided" |
61 |
|
62 |
local PYTHON_PKG_DEP out= |
63 |
- for i in "${_PYTHON_ALL_IMPLS[@]}"; do |
64 |
- has "${i}" "${PYTHON_COMPAT[@]}" || continue |
65 |
- |
66 |
+ for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
67 |
local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)" |
68 |
python_export "${i}" PYTHON_PKG_DEP |
69 |
|
70 |
@@ -242,7 +228,7 @@ _python_EPYTHON_supported() { |
71 |
;; |
72 |
esac |
73 |
|
74 |
- if has "${i}" "${PYTHON_COMPAT[@]}"; then |
75 |
+ if has "${i}" "${_PYTHON_SUPPORTED_IMPLS[@]}"; then |
76 |
if python_is_installed "${i}"; then |
77 |
if declare -f python_check_deps >/dev/null; then |
78 |
local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)" |
79 |
@@ -293,10 +279,8 @@ python_setup() { |
80 |
|
81 |
# fallback to best installed impl. |
82 |
local rev_impls=() |
83 |
- for i in "${_PYTHON_ALL_IMPLS[@]}"; do |
84 |
- if has "${i}" "${PYTHON_COMPAT[@]}"; then |
85 |
- rev_impls=( "${i}" "${rev_impls[@]}" ) |
86 |
- fi |
87 |
+ for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
88 |
+ rev_impls=( "${i}" "${rev_impls[@]}" ) |
89 |
done |
90 |
|
91 |
for i in "${rev_impls[@]}"; do |
92 |
|
93 |
diff --git a/eclass/python-r1.eclass b/eclass/python-r1.eclass |
94 |
index fbc39dc..f7a8541 100644 |
95 |
--- a/eclass/python-r1.eclass |
96 |
+++ b/eclass/python-r1.eclass |
97 |
@@ -82,12 +82,6 @@ inherit multibuild python-utils-r1 |
98 |
# @CODE |
99 |
# PYTHON_COMPAT=( python2_7 python3_{3,4} ) |
100 |
# @CODE |
101 |
-if ! declare -p PYTHON_COMPAT &>/dev/null; then |
102 |
- die 'PYTHON_COMPAT not declared.' |
103 |
-fi |
104 |
-if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then |
105 |
- die 'PYTHON_COMPAT must be an array.' |
106 |
-fi |
107 |
|
108 |
# @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE |
109 |
# @INTERNAL |
110 |
@@ -186,24 +180,17 @@ fi |
111 |
# @CODE |
112 |
|
113 |
_python_set_globals() { |
114 |
- local impls=() |
115 |
- |
116 |
PYTHON_DEPS= |
117 |
local i PYTHON_PKG_DEP |
118 |
- for i in "${PYTHON_COMPAT[@]}"; do |
119 |
- _python_impl_supported "${i}" || continue |
120 |
|
121 |
+ _python_set_impls |
122 |
+ |
123 |
+ for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
124 |
python_export "${i}" PYTHON_PKG_DEP |
125 |
PYTHON_DEPS+="python_targets_${i}? ( ${PYTHON_PKG_DEP} ) " |
126 |
- |
127 |
- impls+=( "${i}" ) |
128 |
done |
129 |
|
130 |
- if [[ ${#impls[@]} -eq 0 ]]; then |
131 |
- die "No supported implementation in PYTHON_COMPAT." |
132 |
- fi |
133 |
- |
134 |
- local flags=( "${impls[@]/#/python_targets_}" ) |
135 |
+ local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" ) |
136 |
local optflags=${flags[@]/%/(-)?} |
137 |
|
138 |
# A nice QA trick here. Since a python-single-r1 package has to have |
139 |
@@ -212,7 +199,7 @@ _python_set_globals() { |
140 |
# it should prevent developers from mistakenly depending on packages |
141 |
# not supporting multiple Python implementations. |
142 |
|
143 |
- local flags_st=( "${impls[@]/#/-python_single_target_}" ) |
144 |
+ local flags_st=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/-python_single_target_}" ) |
145 |
optflags+=,${flags_st[@]/%/(-)} |
146 |
|
147 |
IUSE=${flags[*]} |
148 |
@@ -246,9 +233,7 @@ _python_validate_useflags() { |
149 |
|
150 |
local i |
151 |
|
152 |
- for i in "${PYTHON_COMPAT[@]}"; do |
153 |
- _python_impl_supported "${i}" || continue |
154 |
- |
155 |
+ for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
156 |
use "python_targets_${i}" && return 0 |
157 |
done |
158 |
|
159 |
@@ -290,9 +275,7 @@ python_gen_usedep() { |
160 |
local impl pattern |
161 |
local matches=() |
162 |
|
163 |
- for impl in "${PYTHON_COMPAT[@]}"; do |
164 |
- _python_impl_supported "${impl}" || continue |
165 |
- |
166 |
+ for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
167 |
for pattern; do |
168 |
if [[ ${impl} == ${pattern} ]]; then |
169 |
matches+=( |
170 |
@@ -333,9 +316,7 @@ python_gen_useflags() { |
171 |
local impl pattern |
172 |
local matches=() |
173 |
|
174 |
- for impl in "${PYTHON_COMPAT[@]}"; do |
175 |
- _python_impl_supported "${impl}" || continue |
176 |
- |
177 |
+ for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
178 |
for pattern; do |
179 |
if [[ ${impl} == ${pattern} ]]; then |
180 |
matches+=( "python_targets_${impl}" ) |
181 |
@@ -382,9 +363,7 @@ python_gen_cond_dep() { |
182 |
local dep=${1} |
183 |
shift |
184 |
|
185 |
- for impl in "${PYTHON_COMPAT[@]}"; do |
186 |
- _python_impl_supported "${impl}" || continue |
187 |
- |
188 |
+ for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
189 |
for pattern; do |
190 |
if [[ ${impl} == ${pattern} ]]; then |
191 |
# substitute ${PYTHON_USEDEP} if used |
192 |
@@ -460,12 +439,8 @@ _python_obtain_impls() { |
193 |
|
194 |
MULTIBUILD_VARIANTS=() |
195 |
|
196 |
- for impl in "${_PYTHON_ALL_IMPLS[@]}"; do |
197 |
- if has "${impl}" "${PYTHON_COMPAT[@]}" \ |
198 |
- && use "python_targets_${impl}" |
199 |
- then |
200 |
- MULTIBUILD_VARIANTS+=( "${impl}" ) |
201 |
- fi |
202 |
+ for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
203 |
+ use "python_targets_${impl}" && MULTIBUILD_VARIANTS+=( "${impl}" ) |
204 |
done |
205 |
} |
206 |
|
207 |
|
208 |
diff --git a/eclass/python-single-r1.eclass b/eclass/python-single-r1.eclass |
209 |
index b8684f0..8ef3846 100644 |
210 |
--- a/eclass/python-single-r1.eclass |
211 |
+++ b/eclass/python-single-r1.eclass |
212 |
@@ -95,12 +95,6 @@ if [[ ! ${_PYTHON_SINGLE_R1} ]]; then |
213 |
# @CODE |
214 |
# PYTHON_COMPAT=( python2_7 python3_{3,4} ) |
215 |
# @CODE |
216 |
-if ! declare -p PYTHON_COMPAT &>/dev/null; then |
217 |
- die 'PYTHON_COMPAT not declared.' |
218 |
-fi |
219 |
-if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then |
220 |
- die 'PYTHON_COMPAT must be an array.' |
221 |
-fi |
222 |
|
223 |
# @ECLASS-VARIABLE: PYTHON_REQ_USE |
224 |
# @DEFAULT_UNSET |
225 |
@@ -186,34 +180,24 @@ fi |
226 |
# @CODE |
227 |
|
228 |
_python_single_set_globals() { |
229 |
- local impls=() |
230 |
- local unimpls=() |
231 |
+ _python_set_impls |
232 |
|
233 |
PYTHON_DEPS= |
234 |
local i PYTHON_PKG_DEP |
235 |
- for i in "${_PYTHON_ALL_IMPLS[@]}"; do |
236 |
- has "${i}" "${PYTHON_COMPAT[@]}" \ |
237 |
- && impls+=( "${i}" ) \ |
238 |
- || unimpls+=( "${i}" ) |
239 |
- done |
240 |
- |
241 |
- if [[ ${#impls[@]} -eq 0 ]]; then |
242 |
- die "No supported implementation in PYTHON_COMPAT." |
243 |
- fi |
244 |
|
245 |
- local flags_mt=( "${impls[@]/#/python_targets_}" ) |
246 |
- local flags=( "${impls[@]/#/python_single_target_}" ) |
247 |
- local unflags=( "${unimpls[@]/#/-python_single_target_}" ) |
248 |
+ local flags_mt=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" ) |
249 |
+ local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_single_target_}" ) |
250 |
+ local unflags=( "${_PYTHON_UNSUPPORTED_IMPLS[@]/#/-python_single_target_}" ) |
251 |
|
252 |
local optflags=${flags_mt[@]/%/(-)?},${unflags[@]/%/(-)} |
253 |
|
254 |
IUSE="${flags_mt[*]}" |
255 |
|
256 |
- if [[ ${#impls[@]} -eq 1 ]]; then |
257 |
+ if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then |
258 |
# There is only one supported implementation; set IUSE and other |
259 |
# variables without PYTHON_SINGLE_TARGET. |
260 |
PYTHON_REQUIRED_USE="${flags_mt[*]}" |
261 |
- python_export "${impls[0]}" PYTHON_PKG_DEP |
262 |
+ python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" PYTHON_PKG_DEP |
263 |
PYTHON_DEPS="${PYTHON_PKG_DEP} " |
264 |
# Force on the python_single_target_* flag for this impl, so |
265 |
# that any dependencies that inherit python-single-r1 and |
266 |
@@ -228,7 +212,7 @@ _python_single_set_globals() { |
267 |
# on this package. |
268 |
optflags+=,${flags[@]/%/(+)?} |
269 |
|
270 |
- for i in "${impls[@]}"; do |
271 |
+ for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
272 |
# The chosen targets need to be in PYTHON_TARGETS as well. |
273 |
# This is in order to enforce correct dependencies on packages |
274 |
# supporting multiple implementations. |
275 |
@@ -288,9 +272,7 @@ python_gen_usedep() { |
276 |
local impl pattern |
277 |
local matches=() |
278 |
|
279 |
- for impl in "${PYTHON_COMPAT[@]}"; do |
280 |
- _python_impl_supported "${impl}" || continue |
281 |
- |
282 |
+ for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
283 |
for pattern; do |
284 |
if [[ ${impl} == ${pattern} ]]; then |
285 |
matches+=( |
286 |
@@ -331,9 +313,7 @@ python_gen_useflags() { |
287 |
local impl pattern |
288 |
local matches=() |
289 |
|
290 |
- for impl in "${PYTHON_COMPAT[@]}"; do |
291 |
- _python_impl_supported "${impl}" || continue |
292 |
- |
293 |
+ for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
294 |
for pattern; do |
295 |
if [[ ${impl} == ${pattern} ]]; then |
296 |
matches+=( "python_single_target_${impl}" ) |
297 |
@@ -380,9 +360,7 @@ python_gen_cond_dep() { |
298 |
local dep=${1} |
299 |
shift |
300 |
|
301 |
- for impl in "${PYTHON_COMPAT[@]}"; do |
302 |
- _python_impl_supported "${impl}" || continue |
303 |
- |
304 |
+ for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
305 |
for pattern; do |
306 |
if [[ ${impl} == ${pattern} ]]; then |
307 |
# substitute ${PYTHON_USEDEP} if used |
308 |
@@ -411,20 +389,15 @@ python_setup() { |
309 |
|
310 |
unset EPYTHON |
311 |
|
312 |
- local impl impls=() |
313 |
- for impl in "${PYTHON_COMPAT[@]}"; do |
314 |
- _python_impl_supported "${impl}" || continue |
315 |
- impls+=( "${impl}" ) |
316 |
- done |
317 |
- |
318 |
- if [[ ${#impls[@]} -eq 1 ]]; then |
319 |
- if use "python_targets_${impls[0]}"; then |
320 |
+ if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then |
321 |
+ if use "python_targets_${_PYTHON_SUPPORTED_IMPLS[0]}"; then |
322 |
# Only one supported implementation, enable it explicitly |
323 |
- python_export "${impls[0]}" EPYTHON PYTHON |
324 |
+ python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" EPYTHON PYTHON |
325 |
python_wrapper_setup |
326 |
fi |
327 |
else |
328 |
- for impl in "${impls[@]}"; do |
329 |
+ local impl |
330 |
+ for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do |
331 |
if use "python_single_target_${impl}"; then |
332 |
if [[ ${EPYTHON} ]]; then |
333 |
eerror "Your PYTHON_SINGLE_TARGET setting lists more than a single Python" |
334 |
@@ -452,14 +425,14 @@ python_setup() { |
335 |
|
336 |
if [[ ! ${EPYTHON} ]]; then |
337 |
eerror "No Python implementation selected for the build. Please set" |
338 |
- if [[ ${#impls[@]} -eq 1 ]]; then |
339 |
+ if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then |
340 |
eerror "the PYTHON_TARGETS variable in your make.conf to include one" |
341 |
else |
342 |
eerror "the PYTHON_SINGLE_TARGET variable in your make.conf to one" |
343 |
fi |
344 |
eerror "of the following values:" |
345 |
eerror |
346 |
- eerror "${impls[@]}" |
347 |
+ eerror "${_PYTHON_SUPPORTED_IMPLS[@]}" |
348 |
echo |
349 |
die "No supported Python implementation in PYTHON_SINGLE_TARGET/PYTHON_TARGETS." |
350 |
fi |
351 |
|
352 |
diff --git a/eclass/python-utils-r1.eclass b/eclass/python-utils-r1.eclass |
353 |
index 7830323..89a7cbf 100644 |
354 |
--- a/eclass/python-utils-r1.eclass |
355 |
+++ b/eclass/python-utils-r1.eclass |
356 |
@@ -84,6 +84,55 @@ _python_impl_supported() { |
357 |
esac |
358 |
} |
359 |
|
360 |
+# @FUNCTION: _python_set_impls |
361 |
+# @INTERNAL |
362 |
+# @DESCRIPTION: |
363 |
+# Check PYTHON_COMPAT for well-formedness and validity, then set |
364 |
+# two global variables: |
365 |
+# |
366 |
+# - _PYTHON_SUPPORTED_IMPLS containing valid implementations supported |
367 |
+# by the ebuild (PYTHON_COMPAT - dead implementations), |
368 |
+# |
369 |
+# - and _PYTHON_UNSUPPORTED_IMPLS containing valid implementations that |
370 |
+# are not supported by the ebuild. |
371 |
+# |
372 |
+# Implementations in both variables are ordered using the pre-defined |
373 |
+# eclass implementation ordering. |
374 |
+# |
375 |
+# This function must be called once in global scope by an eclass |
376 |
+# utilizing PYTHON_COMPAT. |
377 |
+_python_set_impls() { |
378 |
+ local i |
379 |
+ |
380 |
+ if ! declare -p PYTHON_COMPAT &>/dev/null; then |
381 |
+ die 'PYTHON_COMPAT not declared.' |
382 |
+ fi |
383 |
+ if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then |
384 |
+ die 'PYTHON_COMPAT must be an array.' |
385 |
+ fi |
386 |
+ for i in "${PYTHON_COMPAT[@]}"; do |
387 |
+ # trigger validity checks |
388 |
+ _python_impl_supported "${i}" |
389 |
+ done |
390 |
+ |
391 |
+ _PYTHON_SUPPORTED_IMPLS=() |
392 |
+ _PYTHON_UNSUPPORTED_IMPLS=() |
393 |
+ |
394 |
+ for i in "${_PYTHON_ALL_IMPLS[@]}"; do |
395 |
+ if has "${i}" "${PYTHON_COMPAT[@]}"; then |
396 |
+ _PYTHON_SUPPORTED_IMPLS+=( "${i}" ) |
397 |
+ else |
398 |
+ _PYTHON_UNSUPPORTED_IMPLS+=( "${i}" ) |
399 |
+ fi |
400 |
+ done |
401 |
+ |
402 |
+ if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 0 ]]; then |
403 |
+ die "No supported implementation in PYTHON_COMPAT." |
404 |
+ fi |
405 |
+ |
406 |
+ readonly _PYTHON_SUPPORTED_IMPLS _PYTHON_UNSUPPORTED_IMPLS |
407 |
+} |
408 |
+ |
409 |
# @ECLASS-VARIABLE: PYTHON |
410 |
# @DEFAULT_UNSET |
411 |
# @DESCRIPTION: |