From d2c3a3108e4cfb57a9da8964bf73b4275ad5a5d6 Mon Sep 17 00:00:00 2001 From: "Aaron W. Swenson" Date: Sun, 3 Sep 2017 10:39:15 -0400 Subject: sync with Gentoo repo --- postgres-multi.eclass | 175 +++++++++++++++++++++++++++++++++++++++++++++++++ postgres.eclass | 177 +++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 314 insertions(+), 38 deletions(-) create mode 100644 postgres-multi.eclass diff --git a/postgres-multi.eclass b/postgres-multi.eclass new file mode 100644 index 0000000..5d40a0e --- /dev/null +++ b/postgres-multi.eclass @@ -0,0 +1,175 @@ +# Copyright 1999-2017 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +inherit multibuild postgres +EXPORT_FUNCTIONS pkg_setup src_prepare src_compile src_install src_test + + +# @ECLASS: postgres-multi.eclass +# @MAINTAINER: +# PostgreSQL +# @AUTHOR: Aaron W. Swenson +# @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:-0} in + 5|6) ;; + *) die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" ;; +esac + + +# @ECLASS-VARIABLE: POSTGRES_COMPAT +# @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: POSTGRES_COMPAT=( 9.4 9.{5,6} ) +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 +# @INTERNAL +# @USAGE: _postgres-multi_multibuild_wrapper [ ...] +# @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=$(which 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: postgres-multi_foreach [ ...] +# @DESCRIPTION: +# Run the given command in the package's build directory for each +# PostgreSQL slot in the intersect of POSTGRES_TARGETS and +# POSTGRES_COMPAT and user-enabled slots. 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: postgres-multi_forbest [ ...] +# @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 +# @USAGE: 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 + + 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 +# @USAGE: 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 $(which 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 + + case ${EAPI:-0} in + 0|1|2|3|4|5) epatch_user ;; + 6) eapply_user ;; + esac + + local MULTIBUILD_VARIANT + local MULTIBUILD_VARIANTS=("${_POSTGRES_INTERSECT_SLOTS[@]}") + multibuild_copy_sources +} + +# @FUNCTION: postgres-multi_src_compile +# @USAGE: postgres-multi_src_compile +# @DESCRIPTION: +# Runs `emake' in each build directory +postgres-multi_src_compile() { + postgres-multi_foreach emake +} + +# @FUNCTION: postgres-multi_src_install +# @USAGE: 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}" +} + +# @FUNCTION: postgres-multi_src_test +# @USAGE: postgres-multi_src_test +# @DESCRIPTION: +# Runs `emake installcheck' in each build directory. +postgres-multi_src_test() { + postgres-multi_foreach emake installcheck +} diff --git a/postgres.eclass b/postgres.eclass index 77851c1..13483a9 100644 --- a/postgres.eclass +++ b/postgres.eclass @@ -1,58 +1,159 @@ -# Copyright 1999-2013 Gentoo Foundation +# Copyright 1999-2017 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: $ + +inherit user +EXPORT_FUNCTIONS pkg_setup # @ECLASS: postgres.eclass # @MAINTAINER: -# Aaron W. Swenson -# @BLURB: Functions to aid PostgreSQL-related packages +# PostgreSQL +# @AUTHOR: Aaron W. Swenson +# @BLURB: An eclass for PostgreSQL-related packages # @DESCRIPTION: -# The postgres eclass is a suite that enable ebuilds to build against -# multiple slots, properly add a new daemon user, and query -# PostgreSQL-related information from the system. +# This eclass provides common utility functions that many +# PostgreSQL-related packages perform, such as checking that the +# currently selected PostgreSQL slot is within a range, adding a system +# user to the postgres system group, and generating dependencies. + + +case ${EAPI:-0} in + 5|6) ;; + *) die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" ;; +esac -inherit user -# @FUNCTION: postgres_depend -# @USAGE: postgres_depend [USE,flags] [server] [server,USE,flags] +# @ECLASS-VARIABLE: POSTGRES_COMPAT +# @DEFAULT_UNSET # @DESCRIPTION: -# Called after DEPEND is declared. Takes up to two optional arguments. The 'server' -postgres_depend() { - if [[ -n ${POSTGRES_ONLY} ]] ; then - DEPEND+=" dev-db/postgresql-base:${POSTGRES_ONLY}[${BASE_FLAGS}]" - elif [[ -n ${POSTGRES_MIN} ]] - if [[ -n ${POSTGRES_MAX} ]] ; then +# A Bash array containing a list of compatible PostgreSQL slots as +# defined by the developer. If declared, must be declared before +# inheriting this eclass. Example: POSTGRES_COMPAT=( 9.4 9.{5,6} ) - else - #blarg - fi - elif [[ -n ${POSGRES_MAX} ]] ; then - #blah +# @ECLASS-VARIABLE: POSTGRES_USEDEP +# @DEFAULT_UNSET +# @DESCRIPTION: +# Add the 2-Style and/or 4-Style use dependencies without brackets to be used +# for POSTGRES_DEP. If declared, must be done before inheriting this eclass. + +# @ECLASS-VARIABLE: POSTGRES_DEP +# @DESCRIPTION: +# An automatically generated dependency string suitable for use in +# DEPEND and RDEPEND declarations. + +# @ECLASS-VARIABLE: POSTGRES_REQ_USE +# @DESCRIPTION: +# An automatically generated REQUIRED_USE-compatible string built upon +# POSTGRES_COMPAT. REQUIRED_USE="... ${POSTGRES_REQ_USE}" is only +# required if the package must build against one of the PostgreSQL slots +# declared in POSTGRES_COMPAT. + +if declare -p POSTGRES_COMPAT &> /dev/null ; then + # Reverse sort the given POSTGRES_COMPAT so that the most recent + # slot is preferred over an older slot. + # -- do we care if dependencies are deterministic by USE flags? + readarray -t POSTGRES_COMPAT < <(printf '%s\n' "${POSTGRES_COMPAT[@]}" | sort -nr) + + POSTGRES_DEP="" + POSTGRES_REQ_USE=" || (" + for slot in "${POSTGRES_COMPAT[@]}" ; do + POSTGRES_DEP+=" postgres_targets_postgres${slot/\./_}? ( dev-db/postgresql:${slot}=" + declare -p POSTGRES_USEDEP &>/dev/null && \ + POSTGRES_DEP+="[${POSTGRES_USEDEP}]" + POSTGRES_DEP+=" )" + + IUSE+=" postgres_targets_postgres${slot/\./_}" + POSTGRES_REQ_USE+=" postgres_targets_postgres${slot/\./_}" + done + POSTGRES_REQ_USE+=" )" +else + POSTGRES_DEP="dev-db/postgresql:=" + declare -p POSTGRES_USEDEP &>/dev/null && \ + POSTGRES_DEP+="[${POSTGRES_USEDEP}]" +fi + + +# @FUNCTION: postgres_check_slot +# @DESCRIPTION: +# Verify that the currently selected PostgreSQL slot is set to one of +# the slots defined in POSTGRES_COMPAT. Automatically dies unless a +# POSTGRES_COMPAT slot is selected. Should be called in pkg_pretend(). +postgres_check_slot() { + if ! declare -p POSTGRES_COMPAT &>/dev/null; then + die 'POSTGRES_COMPAT not declared.' + fi + + # Don't die because we can't run postgresql-config during pretend. + [[ "$EBUILD_PHASE" = "pretend" && -z "$(which postgresql-config 2> /dev/null)" ]] \ + && return 0 + + if has $(postgresql-config show 2> /dev/null) "${POSTGRES_COMPAT[@]}"; then + return 0 else - [[POSTGRES_MAX]] - [[POSTGRES_MIN]] - [[POSTGRES_ONLY]] + eerror "PostgreSQL slot must be set to one of: " + eerror " ${POSTGRES_COMPAT[@]}" + die "Incompatible PostgreSQL slot eselected" fi } -length=$(expr length ${POSTGRES_MAX}) - -pgsql_pkg_setup() { +# @FUNCTION: postgres_new_user +# @DESCRIPTION: +# Creates the "postgres" system group and user -- which is separate from +# the database user -- in addition to the developer defined user. Takes +# the same arguments as "enewuser". +postgres_new_user() { enewgroup postgres 70 enewuser postgres 70 /bin/bash /var/lib/postgresql postgres + + if [[ $# -gt 0 ]] ; then + if [[ "$1" = "postgres" ]] ; then + ewarn "Username 'postgres' implied, skipping" + else + local groups=$5 + [[ -n "${groups}" ]] && groups+=",postgres" || groups="postgres" + enewuser "$1" "${2:--1}" "${3:--1}" "${4:--1}" "${groups}" + fi + fi } -# @FUNCTION: pgsql_enewuser -# @USAGE: [uid] [shell] [homedir] +# @FUNCTION: postgres_pkg_setup +# @USAGE: postgres_pkg_setup # @DESCRIPTION: -# Same as enewuser, in fact it uses enewuser, you are not required to -# understand how to properly add a user to the system. The only required -# parameter is the username. Default uid is (pass -1 for this) next -# available, default shell is /bin/false, default homedir is /dev/null, -# and is assigned to the postgres group. -pgsql_new_user() { - local user=$1 uid=$2 shell=$3 home=$4 +# Initialize environment variable(s) according to the best +# installed version of PostgreSQL that is also in POSTGRES_COMPAT. This +# is required if pkg_setup() is declared in the ebuild. +# Exports PG_SLOT, PG_CONFIG, and PKG_CONFIG_PATH. +postgres_pkg_setup() { + debug-print-function ${FUNCNAME} "${@}" + + local compat_slot + local best_slot + for compat_slot in "${POSTGRES_COMPAT[@]}"; do + if use "postgres_targets_postgres${compat_slot/\./_}"; then + best_slot="${compat_slot}" + break + fi + done + + if [[ -z "${best_slot}" ]]; then + local flags f + for f in "${POSTGRES_COMPAT[@]}"; do + flags+=" postgres${f/./_}" + done + + eerror "POSTGRES_TARGETS must contain at least one of:" + eerror " ${flags}" + die "No suitable POSTGRES_TARGETS enabled." + fi + + export PG_SLOT=${best_slot} + export PG_CONFIG=$(which pg_config${best_slot//./}) + + local pg_pkg_config_path="$(${PG_CONFIG} --libdir)/pkgconfig" + if [[ -n "${PKG_CONFIG_PATH}" ]]; then + export PKG_CONFIG_PATH="${pg_pkg_config_path}:${PKG_CONFIG_PATH}" + else + export PKG_CONFIG_PATH="${pg_pkg_config_path}" + fi - pgsql_pkg_setup - enewuser $1 $2 $3 $4 postgres + elog "PostgreSQL Target: ${best_slot}" } -- cgit v1.2.3-65-gdbad