Browse code

eclass for old mailman

Hanno Böck authored on17/04/2021 15:54:07
Showing1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,529 @@
1
+# Copyright 1999-2021 Gentoo Authors
2
+# Distributed under the terms of the GNU General Public License v2
3
+
4
+# @ECLASS: python-single-r1.eclass
5
+# @MAINTAINER:
6
+# Python team <python@gentoo.org>
7
+# @AUTHOR:
8
+# Author: Michał Górny <mgorny@gentoo.org>
9
+# Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
10
+# @SUPPORTED_EAPIS: 5 6 7
11
+# @BLURB: An eclass for Python packages not installed for multiple implementations.
12
+# @DESCRIPTION:
13
+# An extension of the python-r1 eclass suite for packages which
14
+# don't support being installed for multiple Python implementations.
15
+# This mostly includes tools embedding Python and packages using foreign
16
+# build systems.
17
+#
18
+# This eclass sets correct IUSE.  It also provides PYTHON_DEPS
19
+# and PYTHON_REQUIRED_USE that need to be added to appropriate ebuild
20
+# metadata variables.
21
+#
22
+# The eclass exports PYTHON_SINGLE_USEDEP that is suitable for depending
23
+# on other packages using the eclass.  Dependencies on packages using
24
+# python-r1 should be created via python_gen_cond_dep() function,
25
+# using PYTHON_USEDEP placeholder.
26
+#
27
+# Please note that packages support multiple Python implementations
28
+# (using python-r1 eclass) can not depend on packages not supporting
29
+# them (using this eclass).
30
+#
31
+# Please note that python-single-r1 will always inherit python-utils-r1
32
+# as well. Thus, all the functions defined there can be used
33
+# in the packages using python-single-r1, and there is no need ever
34
+# to inherit both.
35
+#
36
+# For more information, please see the Python Guide:
37
+# https://dev.gentoo.org/~mgorny/python-guide/
38
+
39
+case "${EAPI:-0}" in
40
+	0|1|2|3|4)
41
+		die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
42
+		;;
43
+	5|6|7)
44
+		# EAPI=5 is required for sane USE_EXPAND dependencies
45
+		;;
46
+	*)
47
+		die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
48
+		;;
49
+esac
50
+
51
+if [[ ! ${_PYTHON_SINGLE_R1} ]]; then
52
+
53
+if [[ ${_PYTHON_R1} ]]; then
54
+	die 'python-single-r1.eclass can not be used with python-r1.eclass.'
55
+elif [[ ${_PYTHON_ANY_R1} ]]; then
56
+	die 'python-single-r1.eclass can not be used with python-any-r1.eclass.'
57
+fi
58
+
59
+inherit python-utils-r1
60
+
61
+fi
62
+
63
+EXPORT_FUNCTIONS pkg_setup
64
+
65
+# @ECLASS-VARIABLE: PYTHON_COMPAT
66
+# @REQUIRED
67
+# @DESCRIPTION:
68
+# This variable contains a list of Python implementations the package
69
+# supports. It must be set before the `inherit' call. It has to be
70
+# an array.
71
+#
72
+# Example:
73
+# @CODE
74
+# PYTHON_COMPAT=( python2_7 python3_3 python3_4 )
75
+# @CODE
76
+#
77
+# Please note that you can also use bash brace expansion if you like:
78
+# @CODE
79
+# PYTHON_COMPAT=( python2_7 python3_{3,4} )
80
+# @CODE
81
+
82
+# @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
83
+# @USER_VARIABLE
84
+# @DEFAULT_UNSET
85
+# @DESCRIPTION:
86
+# This variable can be used when working with ebuilds to override
87
+# the in-ebuild PYTHON_COMPAT. It is a string naming the implementation
88
+# which package will be built for. It needs to be specified
89
+# in the calling environment, and not in ebuilds.
90
+#
91
+# It should be noted that in order to preserve metadata immutability,
92
+# PYTHON_COMPAT_OVERRIDE does not affect IUSE nor dependencies.
93
+# The state of PYTHON_SINGLE_TARGET is ignored, and the implementation
94
+# in PYTHON_COMPAT_OVERRIDE is built instead.  Dependencies need to be
95
+# satisfied manually.
96
+#
97
+# Example:
98
+# @CODE
99
+# PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
100
+# @CODE
101
+
102
+# @ECLASS-VARIABLE: PYTHON_REQ_USE
103
+# @DEFAULT_UNSET
104
+# @DESCRIPTION:
105
+# The list of USEflags required to be enabled on the chosen Python
106
+# implementations, formed as a USE-dependency string. It should be valid
107
+# for all implementations in PYTHON_COMPAT, so it may be necessary to
108
+# use USE defaults.
109
+#
110
+# This should be set before calling `inherit'.
111
+#
112
+# Example:
113
+# @CODE
114
+# PYTHON_REQ_USE="gdbm,ncurses(-)?"
115
+# @CODE
116
+#
117
+# It will cause the Python dependencies to look like:
118
+# @CODE
119
+# python_single_target_pythonX_Y? ( dev-lang/python:X.Y[gdbm,ncurses(-)?] )
120
+# @CODE
121
+
122
+# @ECLASS-VARIABLE: PYTHON_DEPS
123
+# @OUTPUT_VARIABLE
124
+# @DESCRIPTION:
125
+# This is an eclass-generated Python dependency string for all
126
+# implementations listed in PYTHON_COMPAT.
127
+#
128
+# The dependency string is conditional on PYTHON_SINGLE_TARGET.
129
+#
130
+# Example use:
131
+# @CODE
132
+# RDEPEND="${PYTHON_DEPS}
133
+#	dev-foo/mydep"
134
+# BDEPEND="${PYTHON_DEPS}"
135
+# @CODE
136
+#
137
+# Example value:
138
+# @CODE
139
+# dev-lang/python-exec:=
140
+# python_single_target_python2_7? ( dev-lang/python:2.7[gdbm] )
141
+# python_single_target_pypy? ( dev-python/pypy[gdbm] )
142
+# @CODE
143
+
144
+# @ECLASS-VARIABLE: PYTHON_SINGLE_USEDEP
145
+# @OUTPUT_VARIABLE
146
+# @DESCRIPTION:
147
+# This is an eclass-generated USE-dependency string which can be used to
148
+# depend on another python-single-r1 package being built for the same
149
+# Python implementations.
150
+#
151
+# If you need to depend on a multi-impl (python-r1) package, use
152
+# python_gen_cond_dep with PYTHON_USEDEP placeholder instead.
153
+#
154
+# Example use:
155
+# @CODE
156
+# RDEPEND="dev-python/foo[${PYTHON_SINGLE_USEDEP}]"
157
+# @CODE
158
+#
159
+# Example value:
160
+# @CODE
161
+# python_single_target_python3_4(-)?
162
+# @CODE
163
+
164
+# @ECLASS-VARIABLE: PYTHON_USEDEP
165
+# @OUTPUT_VARIABLE
166
+# @DESCRIPTION:
167
+# This is a placeholder variable supported by python_gen_cond_dep,
168
+# in order to depend on python-r1 packages built for the same Python
169
+# implementations.
170
+#
171
+# Example use:
172
+# @CODE
173
+# RDEPEND="$(python_gen_cond_dep '
174
+#     dev-python/foo[${PYTHON_USEDEP}]
175
+#   ')"
176
+# @CODE
177
+#
178
+# Example value:
179
+# @CODE
180
+# python_targets_python3_4(-)
181
+# @CODE
182
+
183
+# @ECLASS-VARIABLE: PYTHON_MULTI_USEDEP
184
+# @OUTPUT_VARIABLE
185
+# @DESCRIPTION:
186
+# This is a backwards-compatibility placeholder.  Use PYTHON_USEDEP
187
+# instead.
188
+
189
+# @ECLASS-VARIABLE: PYTHON_REQUIRED_USE
190
+# @OUTPUT_VARIABLE
191
+# @DESCRIPTION:
192
+# This is an eclass-generated required-use expression which ensures
193
+# that exactly one PYTHON_SINGLE_TARGET value has been enabled.
194
+#
195
+# This expression should be utilized in an ebuild by including it in
196
+# REQUIRED_USE, optionally behind a use flag.
197
+#
198
+# Example use:
199
+# @CODE
200
+# REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )"
201
+# @CODE
202
+#
203
+# Example value:
204
+# @CODE
205
+# ^^ ( python_single_target_python2_7 python_single_target_python3_3 )
206
+# @CODE
207
+
208
+_python_single_set_globals() {
209
+	_python_set_impls
210
+
211
+	local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_single_target_}" )
212
+
213
+	if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
214
+		# if only one implementation is supported, use IUSE defaults
215
+		# to avoid requesting the user to enable it
216
+		IUSE="+${flags[0]}"
217
+	else
218
+		IUSE="${flags[*]}"
219
+	fi
220
+
221
+	local requse="^^ ( ${flags[*]} )"
222
+	local single_flags="${flags[@]/%/(-)?}"
223
+	local single_usedep=${single_flags// /,}
224
+
225
+	local deps= i PYTHON_PKG_DEP
226
+	for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
227
+		_python_export "${i}" PYTHON_PKG_DEP
228
+		# 1) well, python-exec would suffice as an RDEP
229
+		# but no point in making this overcomplex, BDEP doesn't hurt anyone
230
+		# 2) python-exec should be built with all targets forced anyway
231
+		# but if new targets were added, we may need to force a rebuild
232
+		deps+="python_single_target_${i}? (
233
+			${PYTHON_PKG_DEP}
234
+			>=dev-lang/python-exec-2:=[python_targets_${i}]
235
+		) "
236
+	done
237
+
238
+	if [[ ${PYTHON_DEPS+1} ]]; then
239
+		if [[ ${PYTHON_DEPS} != "${deps}" ]]; then
240
+			eerror "PYTHON_DEPS have changed between inherits (PYTHON_REQ_USE?)!"
241
+			eerror "Before: ${PYTHON_DEPS}"
242
+			eerror "Now   : ${deps}"
243
+			die "PYTHON_DEPS integrity check failed"
244
+		fi
245
+
246
+		# these two are formality -- they depend on PYTHON_COMPAT only
247
+		if [[ ${PYTHON_REQUIRED_USE} != ${requse} ]]; then
248
+			eerror "PYTHON_REQUIRED_USE have changed between inherits!"
249
+			eerror "Before: ${PYTHON_REQUIRED_USE}"
250
+			eerror "Now   : ${requse}"
251
+			die "PYTHON_REQUIRED_USE integrity check failed"
252
+		fi
253
+
254
+		if [[ ${PYTHON_SINGLE_USEDEP} != "${single_usedep}" ]]; then
255
+			eerror "PYTHON_SINGLE_USEDEP have changed between inherits!"
256
+			eerror "Before: ${PYTHON_SINGLE_USEDEP}"
257
+			eerror "Now   : ${single_usedep}"
258
+			die "PYTHON_SINGLE_USEDEP integrity check failed"
259
+		fi
260
+	else
261
+		PYTHON_DEPS=${deps}
262
+		PYTHON_REQUIRED_USE=${requse}
263
+		PYTHON_USEDEP='%PYTHON_USEDEP-NEEDS-TO-BE-USED-IN-PYTHON_GEN_COND_DEP%'
264
+		PYTHON_SINGLE_USEDEP=${single_usedep}
265
+		readonly PYTHON_DEPS PYTHON_REQUIRED_USE PYTHON_SINGLE_USEDEP \
266
+			PYTHON_USEDEP
267
+	fi
268
+}
269
+_python_single_set_globals
270
+unset -f _python_single_set_globals
271
+
272
+if [[ ! ${_PYTHON_SINGLE_R1} ]]; then
273
+
274
+# @FUNCTION: _python_gen_usedep
275
+# @USAGE: [<pattern>...]
276
+# @INTERNAL
277
+# @DESCRIPTION:
278
+# Output a USE dependency string for Python implementations which
279
+# are both in PYTHON_COMPAT and match any of the patterns passed
280
+# as parameters to the function.
281
+#
282
+# The patterns can be either fnmatch-style patterns (matched via bash
283
+# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
284
+# appropriately all enabled Python 2/3 implementations (alike
285
+# python_is_python3). Remember to escape or quote the fnmatch patterns
286
+# to prevent accidental shell filename expansion.
287
+#
288
+# This is an internal function used to implement python_gen_cond_dep.
289
+_python_gen_usedep() {
290
+	debug-print-function ${FUNCNAME} "${@}"
291
+
292
+	local impl matches=()
293
+
294
+	_python_verify_patterns "${@}"
295
+	for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
296
+		if _python_impl_matches "${impl}" "${@}"; then
297
+			matches+=(
298
+				"python_single_target_${impl}(-)?"
299
+			)
300
+		fi
301
+	done
302
+
303
+	[[ ${matches[@]} ]] || die "No supported implementations match python_gen_usedep patterns: ${@}"
304
+
305
+	local out=${matches[@]}
306
+	echo "${out// /,}"
307
+}
308
+
309
+# @FUNCTION: python_gen_useflags
310
+# @USAGE: [<pattern>...]
311
+# @DESCRIPTION:
312
+# Output a list of USE flags for Python implementations which
313
+# are both in PYTHON_COMPAT and match any of the patterns passed
314
+# as parameters to the function.
315
+#
316
+# The patterns can be either fnmatch-style patterns (matched via bash
317
+# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
318
+# appropriately all enabled Python 2/3 implementations (alike
319
+# python_is_python3). Remember to escape or quote the fnmatch patterns
320
+# to prevent accidental shell filename expansion.
321
+#
322
+# Example:
323
+# @CODE
324
+# PYTHON_COMPAT=( python{2_7,3_4} )
325
+# REQUIRED_USE="doc? ( ^^ ( $(python_gen_useflags 'python2*') ) )"
326
+# @CODE
327
+#
328
+# It will cause the variable to look like:
329
+# @CODE
330
+# REQUIRED_USE="doc? ( ^^ ( python_single_target_python2_7 ) )"
331
+# @CODE
332
+python_gen_useflags() {
333
+	debug-print-function ${FUNCNAME} "${@}"
334
+
335
+	local impl matches=()
336
+
337
+	_python_verify_patterns "${@}"
338
+	for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
339
+		if _python_impl_matches "${impl}" "${@}"; then
340
+			matches+=( "python_single_target_${impl}" )
341
+		fi
342
+	done
343
+
344
+	echo "${matches[@]}"
345
+}
346
+
347
+# @FUNCTION: python_gen_cond_dep
348
+# @USAGE: <dependency> [<pattern>...]
349
+# @DESCRIPTION:
350
+# Output a list of <dependency>-ies made conditional to USE flags
351
+# of Python implementations which are both in PYTHON_COMPAT and match
352
+# any of the patterns passed as the remaining parameters.
353
+#
354
+# The patterns can be either fnmatch-style patterns (matched via bash
355
+# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
356
+# appropriately all enabled Python 2/3 implementations (alike
357
+# python_is_python3). Remember to escape or quote the fnmatch patterns
358
+# to prevent accidental shell filename expansion.
359
+#
360
+# In order to enforce USE constraints on the packages, verbatim
361
+# '${PYTHON_SINGLE_USEDEP}' and '${PYTHON_USEDEP}' (quoted!) may
362
+# be placed in the dependency specification. It will get expanded within
363
+# the function into a proper USE dependency string.
364
+#
365
+# Example:
366
+# @CODE
367
+# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
368
+# RDEPEND="$(python_gen_cond_dep \
369
+#   'dev-python/unittest2[${PYTHON_USEDEP}]' python2_7 pypy )"
370
+# @CODE
371
+#
372
+# It will cause the variable to look like:
373
+# @CODE
374
+# RDEPEND="python_single_target_python2_7? (
375
+#     dev-python/unittest2[python_targets_python2_7(-)?,...] )
376
+#	python_single_target_pypy? (
377
+#     dev-python/unittest2[python_targets_pypy(-)?,...] )"
378
+# @CODE
379
+python_gen_cond_dep() {
380
+	debug-print-function ${FUNCNAME} "${@}"
381
+
382
+	local impl matches=()
383
+
384
+	local dep=${1}
385
+	shift
386
+
387
+	_python_verify_patterns "${@}"
388
+	for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
389
+		if _python_impl_matches "${impl}" "${@}"; then
390
+			# substitute ${PYTHON_SINGLE_USEDEP} if used
391
+			# (since python_gen_usedep() will not return
392
+			#  ${PYTHON_SINGLE_USEDEP}, the code is run at most once)
393
+			if [[ ${dep} == *'${PYTHON_SINGLE_USEDEP}'* ]]; then
394
+				local usedep=$(_python_gen_usedep "${@}")
395
+				dep=${dep//\$\{PYTHON_SINGLE_USEDEP\}/${usedep}}
396
+			fi
397
+			local multi_usedep="python_targets_${impl}(-)"
398
+
399
+			local subdep=${dep//\$\{PYTHON_MULTI_USEDEP\}/${multi_usedep}}
400
+			matches+=( "python_single_target_${impl}? (
401
+				${subdep//\$\{PYTHON_USEDEP\}/${multi_usedep}} )" )
402
+		fi
403
+	done
404
+
405
+	echo "${matches[@]}"
406
+}
407
+
408
+# @FUNCTION: python_gen_impl_dep
409
+# @USAGE: [<requested-use-flags> [<impl-pattern>...]]
410
+# @DESCRIPTION:
411
+# Output a dependency on Python implementations with the specified USE
412
+# dependency string appended, or no USE dependency string if called
413
+# without the argument (or with empty argument). If any implementation
414
+# patterns are passed, the output dependencies will be generated only
415
+# for the implementations matching them.
416
+#
417
+# The patterns can be either fnmatch-style patterns (matched via bash
418
+# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
419
+# appropriately all enabled Python 2/3 implementations (alike
420
+# python_is_python3). Remember to escape or quote the fnmatch patterns
421
+# to prevent accidental shell filename expansion.
422
+#
423
+# Use this function when you need to request different USE flags
424
+# on the Python interpreter depending on package's USE flags. If you
425
+# only need a single set of interpreter USE flags, just set
426
+# PYTHON_REQ_USE and use ${PYTHON_DEPS} globally.
427
+#
428
+# Example:
429
+# @CODE
430
+# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
431
+# RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )"
432
+# @CODE
433
+#
434
+# It will cause the variable to look like:
435
+# @CODE
436
+# RDEPEND="foo? (
437
+#   python_single_target_python2_7? (
438
+#     dev-lang/python:2.7[xml(+)] )
439
+#	python_single_target_pypy? (
440
+#     dev-python/pypy[xml(+)] ) )"
441
+# @CODE
442
+python_gen_impl_dep() {
443
+	debug-print-function ${FUNCNAME} "${@}"
444
+
445
+	local impl
446
+	local matches=()
447
+
448
+	local PYTHON_REQ_USE=${1}
449
+	shift
450
+
451
+	_python_verify_patterns "${@}"
452
+	for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
453
+		if _python_impl_matches "${impl}" "${@}"; then
454
+			local PYTHON_PKG_DEP
455
+			_python_export "${impl}" PYTHON_PKG_DEP
456
+			matches+=( "python_single_target_${impl}? ( ${PYTHON_PKG_DEP} )" )
457
+		fi
458
+	done
459
+
460
+	echo "${matches[@]}"
461
+}
462
+
463
+# @FUNCTION: python_setup
464
+# @DESCRIPTION:
465
+# Determine what the selected Python implementation is and set
466
+# the Python build environment up for it.
467
+python_setup() {
468
+	debug-print-function ${FUNCNAME} "${@}"
469
+
470
+	unset EPYTHON
471
+
472
+	# support developer override
473
+	if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
474
+		local impls=( ${PYTHON_COMPAT_OVERRIDE} )
475
+		[[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-single-r1"
476
+
477
+		ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
478
+		ewarn "implementation will be used:"
479
+		ewarn
480
+		ewarn "	${PYTHON_COMPAT_OVERRIDE}"
481
+		ewarn
482
+		ewarn "Dependencies won't be satisfied, and PYTHON_SINGLE_TARGET flags will be ignored."
483
+
484
+		_python_export "${impls[0]}" EPYTHON PYTHON
485
+		_python_wrapper_setup
486
+		einfo "Using ${EPYTHON} to build"
487
+		return
488
+	fi
489
+
490
+	local impl
491
+	for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
492
+		if use "python_single_target_${impl}"; then
493
+			if [[ ${EPYTHON} ]]; then
494
+				eerror "Your PYTHON_SINGLE_TARGET setting lists more than a single Python"
495
+				eerror "implementation. Please set it to just one value. If you need"
496
+				eerror "to override the value for a single package, please use package.env"
497
+				eerror "or an equivalent solution (man 5 portage)."
498
+				echo
499
+				die "More than one implementation in PYTHON_SINGLE_TARGET."
500
+			fi
501
+
502
+			_python_export "${impl}" EPYTHON PYTHON
503
+			_python_wrapper_setup
504
+			einfo "Using ${EPYTHON} to build"
505
+		fi
506
+	done
507
+
508
+	if [[ ! ${EPYTHON} ]]; then
509
+		eerror "No Python implementation selected for the build. Please set"
510
+		eerror "the PYTHON_SINGLE_TARGET variable in your make.conf to one"
511
+		eerror "of the following values:"
512
+		eerror
513
+		eerror "${_PYTHON_SUPPORTED_IMPLS[@]}"
514
+		echo
515
+		die "No supported Python implementation in PYTHON_SINGLE_TARGET."
516
+	fi
517
+}
518
+
519
+# @FUNCTION: python-single-r1_pkg_setup
520
+# @DESCRIPTION:
521
+# Runs python_setup.
522
+python-single-r1_pkg_setup() {
523
+	debug-print-function ${FUNCNAME} "${@}"
524
+
525
+	[[ ${MERGE_TYPE} != binary ]] && python_setup
526
+}
527
+
528
+_PYTHON_SINGLE_R1=1
529
+fi