summaryrefslogtreecommitdiff
blob: d93df851cd24700ff7b1d9eccc0978cc3212936e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# Copyright 1999-2022 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

# @ECLASS: postgres-multi.eclass
# @MAINTAINER:
# PostgreSQL <pgsql-bugs@gentoo.org>
# @AUTHOR:
# Aaron W. Swenson <titanofold@gentoo.org>
# @SUPPORTED_EAPIS: 7
# @PROVIDES: multibuild postgres
# @BLURB: An eclass to build PostgreSQL-related packages against multiple slots
# @DESCRIPTION:
# postgres-multi enables ebuilds, particularly PostgreSQL extensions, to
# build and install for one or more PostgreSQL slots as specified by
# POSTGRES_TARGETS use flags.

case ${EAPI} in
	7) ;;
	*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
esac

if [[ ! ${_POSTGRES_MULTI_ECLASS} ]]; then
_POSTGRES_MULTI_ECLASS=1

inherit multibuild postgres

# @ECLASS_VARIABLE: POSTGRES_COMPAT
# @PRE_INHERIT
# @REQUIRED
# @DESCRIPTION:
# A Bash array containing a list of compatible PostgreSQL slots as
# defined by the developer. Must be declared before inheriting this
# eclass. Example:
#@CODE
#POSTGRES_COMPAT=( 9.2 9.3 9.4 9.5 9.6 10 )
#POSTGRES_COMPAT=( 9.{2,3} 9.{4..6} 10 ) # Same as previous
#@CODE
if ! declare -p POSTGRES_COMPAT &>/dev/null; then
	die 'Required variable POSTGRES_COMPAT not declared.'
fi

# @ECLASS_VARIABLE: _POSTGRES_INTERSECT_SLOTS
# @INTERNAL
# @DESCRIPTION:
# A Bash array containing the intersect of POSTGRES_TARGETS and
# POSTGRES_COMPAT.
export _POSTGRES_INTERSECT_SLOTS=( )

# @FUNCTION: _postgres-multi_multibuild_wrapper
# @USAGE: <command> [arg ...]
# @INTERNAL
# @DESCRIPTION:
# For the given variant, set the values of the PG_SLOT, PG_CONFIG, and
# PKG_CONFIG_PATH environment variables accordingly and replace any
# appearance of @PG_SLOT@ in the command and arguments with value of
# ${PG_SLOT}.
_postgres-multi_multibuild_wrapper() {
	debug-print-function ${FUNCNAME} "${@}"
	export PG_SLOT=${MULTIBUILD_VARIANT}
	export PG_CONFIG=$(type -P pg_config${MULTIBUILD_VARIANT//./})
	if [[ -n ${PKG_CONFIG_PATH} ]] ; then
		PKG_CONFIG_PATH="$(${PG_CONFIG} --libdir)/pkgconfig:${PKG_CONFIG_PATH}"
	else
		PKG_CONFIG_PATH="$(${PG_CONFIG} --libdir)/pkgconfig"
	fi
	export PKG_CONFIG_PATH

	$(echo "${@}" | sed "s/@PG_SLOT@/${PG_SLOT}/g")
}

# @FUNCTION: postgres-multi_foreach
# @USAGE: <command> [arg ...]
# @DESCRIPTION:
# Run the given command in the package's build directory for each
# PostgreSQL slot in the intersect of POSTGRES_TARGETS and
# POSTGRES_COMPAT. The PG_CONFIG and PKG_CONFIG_PATH environment
# variables are updated on each iteration to point to the matching
# pg_config command and pkg-config metadata files, respectively, for the
# current slot. Any appearance of @PG_SLOT@ in the command or arguments
# will be substituted with the slot (e.g., 9.5) of the current
# iteration.
postgres-multi_foreach() {
	local MULTIBUILD_VARIANTS=("${_POSTGRES_INTERSECT_SLOTS[@]}")

	multibuild_foreach_variant \
		_postgres-multi_multibuild_wrapper run_in_build_dir ${@}
}

# @FUNCTION: postgres-multi_forbest
# @USAGE: <command> [arg ...]
# @DESCRIPTION:
# Run the given command in the package's build directory for the highest
# slot in the intersect of POSTGRES_COMPAT and POSTGRES_TARGETS. The
# PG_CONFIG and PKG_CONFIG_PATH environment variables are set to the
# matching pg_config command and pkg-config metadata files,
# respectively. Any appearance of @PG_SLOT@ in the command or arguments
# will be substituted with the matching slot (e.g., 9.5).
postgres-multi_forbest() {
	# POSTGRES_COMPAT is reverse sorted once in postgres.eclass so
	# element 0 has the highest slot version.
	local MULTIBUILD_VARIANTS=("${_POSTGRES_INTERSECT_SLOTS[0]}")

	multibuild_foreach_variant \
		_postgres-multi_multibuild_wrapper run_in_build_dir ${@}
}

# @FUNCTION: postgres-multi_pkg_setup
# @DESCRIPTION:
# Initialize internal environment variable(s). This is required if
# pkg_setup() is declared in the ebuild.
postgres-multi_pkg_setup() {
	local user_slot

	# _POSTGRES_COMPAT is created in postgres.eclass
	for user_slot in "${_POSTGRES_COMPAT[@]}"; do
		use "postgres_targets_postgres${user_slot/\./_}" && \
			_POSTGRES_INTERSECT_SLOTS+=( "${user_slot}" )
	done

	if [[ "${#_POSTGRES_INTERSECT_SLOTS[@]}" -eq "0" ]]; then
		die "One of the postgres_targets_postgresSL_OT use flags must be enabled"
	fi

	einfo "Multibuild variants: ${_POSTGRES_INTERSECT_SLOTS[@]}"
}

# @FUNCTION: postgres-multi_src_prepare
# @DESCRIPTION:
# Calls eapply_user then copies ${S} into a build directory for each
# intersect of POSTGRES_TARGETS and POSTGRES_COMPAT.
postgres-multi_src_prepare() {
	if [[ "${#_POSTGRES_INTERSECT_SLOTS[@]}" -eq "0" ]]; then
		eerror "Internal array _POSTGRES_INTERSECT_SLOTS is empty."
		die "Did you forget to call postgres-multi_pkg_setup?"
	fi

	# Check that the slot has been emerged (Should be prevented by
	# Portage, but won't be caught by /usr/bin/ebuild)
	local slot
	for slot in ${_POSTGRES_INTERSECT_SLOTS[@]} ; do
		if [[ -z $(type -P pg_config${slot/.} 2> /dev/null) ]] ; then
			eerror
			eerror "postgres_targets_postgres${slot/.} use flag is enabled, but hasn't been emerged."
			eerror
			die "a postgres_targets use flag is enabled, but not emerged"
		fi
	done

	eapply_user

	local MULTIBUILD_VARIANT
	local MULTIBUILD_VARIANTS=("${_POSTGRES_INTERSECT_SLOTS[@]}")
	multibuild_copy_sources
}

# @FUNCTION: postgres-multi_src_compile
# @DESCRIPTION:
# Runs `emake' in each build directory
postgres-multi_src_compile() {
	postgres-multi_foreach emake
}

# @FUNCTION: postgres-multi_src_test
# @DESCRIPTION:
# Runs `emake installcheck' in each build directory.
postgres-multi_src_test() {
	postgres-multi_foreach emake installcheck
}

# @FUNCTION: postgres-multi_src_install
# @DESCRIPTION:
# Runs `emake install DESTDIR="${D}"' in each build directory.
postgres-multi_src_install() {
	postgres-multi_foreach emake install DESTDIR="${D}"
}

fi

EXPORT_FUNCTIONS pkg_setup src_prepare src_compile src_install src_test