aboutsummaryrefslogtreecommitdiff
path: root/eclass
diff options
context:
space:
mode:
Diffstat (limited to 'eclass')
-rw-r--r--eclass/alternatives-2.eclass138
1 files changed, 100 insertions, 38 deletions
diff --git a/eclass/alternatives-2.eclass b/eclass/alternatives-2.eclass
index fe2f55e95..42150c0db 100644
--- a/eclass/alternatives-2.eclass
+++ b/eclass/alternatives-2.eclass
@@ -1,16 +1,35 @@
-# Copyright 2010-2013 Gentoo Foundation
+# Copyright 2010-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $
+# $Header: $
# Based in part upon 'alternatives.exlib' from Exherbo, which is:
# Copyright 2008, 2009 Bo Ørsted Andresen
# Copyright 2008, 2009 Mike Kelly
# Copyright 2009 David Leverton
+# @ECLASS: alternatives-2
+# @MAINTAINER:
+# Gentoo Science Project <sci@gentoo.org>
+# @BLURB: Manage alternative implementations.
+# @DESCRIPTION:
+# Autogenerate eselect modules for alternatives and ensure that valid provider
+# is set.
+#
+# Remove eselect modules when last provider is unmerged.
+#
# If your package provides pkg_postinst or pkg_prerm phases, you need to be
-# sure you explicitly run alternatives_pkg_{postinst,prerm} where appropriate.
-
-ALTERNATIVES_DIR="/etc/env.d/alternatives"
+# sure you explicitly run alternatives-2_pkg_{postinst,prerm} where appropriate.
+
+case "${EAPI:-0}" in
+ 0|1|2|3)
+ die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
+ ;;
+ 4|5)
+ ;;
+ *)
+ die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
+ ;;
+esac
DEPEND=">=app-admin/eselect-1.4-r100"
RDEPEND="${DEPEND}
@@ -18,30 +37,50 @@ RDEPEND="${DEPEND}
!app-admin/eselect-cblas
!app-admin/eselect-lapack"
-# alternatives_for alternative provider importance source target [ source target [...]]
-alternatives_for() {
- #echo alternatives_for "${@}"
+EXPORT_FUNCTIONS pkg_postinst pkg_prerm
+# @ECLASS-VARIABLE: ALTERNATIVES_DIR
+# @INTERNAL
+# @DESCRIPTION:
+# Alternatives directory with symlinks managed by eselect.
+ALTERNATIVES_DIR="/etc/env.d/alternatives"
+
+# @FUNCTION: alternatives_for
+# @USAGE: alternative provider importance source target [source target [...]]
+# @DESCRIPTION:
+# Set up alternative provider.
+#
+# EXAMPLE:
+# @CODE
+# alternatives_for cblas atlas 0 \
+# /usr/$(get_libdir)/pkgconfig/cblas.pc atlas-cblas.pc \
+# /usr/include/cblas.h atlas/cblas.h
+# @CODE
+alternatives_for() {
(( $# >= 5 )) && (( ($#-3)%2 == 0)) || die "${FUNCNAME} requires exactly 3+N*2 arguments where N>=1"
- local x dupl alternative=${1} provider=${2} importance=${3} index unique src target ret=0
+ local alternative=${1} provider=${2} importance=${3} index src target ret=0
shift 3
- # make sure importance is a signed integer
+ # Make sure importance is a signed integer
if [[ -n ${importance} ]] && ! [[ ${importance} =~ ^[0-9]+(\.[0-9]+)*$ ]]; then
eerror "Invalid importance (${importance}) detected"
((ret++))
fi
+ # Create alternative provider subdirectories under ALTERNATIVES_DIR if needed
[[ -d "${ED}${ALTERNATIVES_DIR}/${alternative}/${provider}" ]] || dodir "${ALTERNATIVES_DIR}/${alternative}/${provider}"
- # keep track of provided alternatives for use in pkg_{postinst,prerm}. keep a mapping between importance and
- # provided alternatives and make sure the former is set to only one value
+ # Keep track of provided alternatives for use in pkg_{postinst,prerm}.
+ # Keep a mapping between importance and provided alternatives
+ # and make sure the former is set to only one value.
if ! has "${alternative}:${provider}" "${ALTERNATIVES_PROVIDED[@]}"; then
+ # Add new provider and set its importance
index=${#ALTERNATIVES_PROVIDED[@]}
ALTERNATIVES_PROVIDED+=( "${alternative}:${provider}" )
ALTERNATIVES_IMPORTANCE[index]=${importance}
[[ -n ${importance} ]] && echo "${importance}" > "${ED}${ALTERNATIVES_DIR}/${alternative}/${provider}/_importance"
else
+ # Set importance for existing provider
for((index=0;index<${#ALTERNATIVES_PROVIDED[@]};index++)); do
if [[ ${alternative}:${provider} == ${ALTERNATIVES_PROVIDED[index]} ]]; then
if [[ -n ${ALTERNATIVES_IMPORTANCE[index]} ]]; then
@@ -57,6 +96,7 @@ alternatives_for() {
done
fi
+ # Process source-target pairs
while (( $# >= 2 )); do
src=${1//+(\/)/\/}; target=${2//+(\/)/\/}
if [[ ${src} != /* ]]; then
@@ -76,8 +116,9 @@ alternatives_for() {
dodir "${ALTERNATIVES_DIR}/${alternative}/${provider}${src%/*}"
dosym "${reltarget}" "${ALTERNATIVES_DIR}/${alternative}/${provider}${src}"
- # say ${ED}/sbin/init exists and links to /bin/systemd (which doesn't exist yet)
- # the -e test will fail, so check for -L also
+ # The -e test will fail if existing symlink points to non-existing target,
+ # so check for -L also.
+ # Say ${ED}/sbin/init exists and links to /bin/systemd (which doesn't exist yet).
if [[ -e ${ED}${src} || -L ${ED}${src} ]]; then
local fulltarget=${target}
[[ ${fulltarget} != /* ]] && fulltarget=${src%/*}/${fulltarget}
@@ -91,34 +132,48 @@ alternatives_for() {
shift 2
done
+ # Stop if there were any errors
[[ ${ret} -eq 0 ]] || die "Errors detected for ${provider}, provided for ${alternative}"
}
+# @FUNCTION: cleanup_old_alternatives_module
+# @USAGE: alternative
+# @DESCRIPTION:
+# Remove old alternatives module.
cleanup_old_alternatives_module() {
local alt=${1} old_module="${EROOT%/}/usr/share/eselect/modules/${alt}.eselect"
- if [[ -f "${old_module}" && "$(source "${old_module}" &>/dev/null; echo "${ALTERNATIVE}")" == "${alt}" ]]; then
- local version="$(source "${old_module}" &>/dev/null; echo "${VERSION}")"
+ if [[ -f "${old_module}" && $(grep 'ALTERNATIVE=' "${old_module}" | cut -d '=' -f 2) == "${alt}" ]]; then
+ local version="$(grep 'VERSION=' "${old_module}" | grep -o '[0-9.]\+')"
if [[ "${version}" == "0.1" || "${version}" == "20080924" ]]; then
- echo rm "${old_module}"
+ echo "rm ${old_module}"
rm "${old_module}" || eerror "rm ${old_module} failed"
fi
fi
}
+# @FUNCTION: alternatives-2_pkg_postinst
+# @DESCRIPTION:
+# Create eselect modules for all provided alternatives if necessary and ensure
+# that valid provider is set.
+#
+# Also remove old eselect modules for provided alternatives.
+#
+# Provided alternatives are set up using alternatives_for().
alternatives-2_pkg_postinst() {
local a alt provider module_version="20090908"
+ local EAUTO="${EROOT%/}/usr/share/eselect/modules/auto"
for a in "${ALTERNATIVES_PROVIDED[@]}"; do
alt="${a%:*}"
provider="${a#*:}"
- if [[ ! -f "${EROOT%/}/usr/share/eselect/modules/auto/${alt}.eselect" \
- || "$(source "${EROOT%/}/usr/share/eselect/modules/auto/${alt}.eselect" &>/dev/null; echo "${VERSION}")" \
+ if [[ ! -f "${EAUTO}/${alt}.eselect" \
+ || "$(grep '^VERSION=' "${EAUTO}/${alt}.eselect" | grep -o '[0-9]\+')" \
-ne "${module_version}" ]]; then
- #einfo "Creating alternatives module for ${alt}"
- if [[ ! -d ${EROOT%/}/usr/share/eselect/modules/auto ]]; then
- install -d "${EROOT%/}"/usr/share/eselect/modules/auto || eerror "Could not create eselect modules dir"
+ if [[ ! -d ${EAUTO} ]]; then
+ install -d "${EAUTO}" || eerror "Could not create eselect modules dir"
fi
- cat > "${EROOT%/}/usr/share/eselect/modules/auto/${alt}.eselect" <<-EOF
- # This module was automatically generated by alternatives.eclass
+ einfo "Creating alternatives eselect module for ${alt}"
+ cat > "${EAUTO}/${alt}.eselect" <<-EOF
+ # This module was automatically generated by alternatives-2.eclass
DESCRIPTION="Alternatives for ${alt}"
VERSION="${module_version}"
MAINTAINER="eselect@gentoo.org"
@@ -130,36 +185,43 @@ alternatives-2_pkg_postinst() {
EOF
fi
- #echo eselect "${alt}" update "${provider}"
- einfo "Creating ${provider} alternative module for ${alt}"
+ # Set alternative provider if there is no valid provider selected
eselect "${alt}" update "${provider}"
cleanup_old_alternatives_module ${alt}
done
}
+# @FUNCTION: alternatives-2_pkg_prerm
+# @DESCRIPTION:
+# Ensure a valid provider is set in case the package is unmerged and
+# remove autogenerated eselect modules for all alternatives when last
+# provider is unmerged.
+#
+# Provided alternatives are set up using alternatives_for().
alternatives-2_pkg_prerm() {
- local a alt provider p ignore
- [[ -n ${REPLACED_BY_ID} ]] || ignore=" --ignore"
+ local a alt provider ignore ret
+ local EAUTO="${EROOT%/}/usr/share/eselect/modules/auto"
+ # If we are uninstalling, update alternatives to valid provider
+ [[ -n ${REPLACED_BY_VERSION} ]] || ignore="--ignore"
for a in "${ALTERNATIVES_PROVIDED[@]}"; do
alt="${a%:*}"
provider="${a#*:}"
- #echo "Making sure ${alt} has a valid provider"
- #echo eselect "${alt}" update${ignore} "${provider}"
- eselect "${alt}" update${ignore} "${provider}" && continue
- einfo "Removing ${provider} alternative module for ${alt}, current is $(eselect ${alt} show)"
- case $? in
+ eselect "${alt}" update ${ignore} "${provider}"
+ ret=$?
+ [[ -n ${REPLACED_BY_VERSION} ]] || \
+ einfo "Removing ${provider} alternative module for ${alt}, current is $(eselect ${alt} show)"
+ case ${ret} in
0) : ;;
2)
+ # This was last provider for the alternative, remove eselect module
einfo "Cleaning up unused alternatives module for ${alt}"
- rm "${EROOT%/}/usr/share/eselect/modules/auto/${alt}.eselect" || \
- eerror rm "${EROOT%/}/usr/share/eselect/modules/auto/${alt}.eselect" failed
+ rm "${EAUTO}/${alt}.eselect" || \
+ eerror "rm ${EAUTO}/${alt}.eselect failed"
;;
*)
- eerror eselect "${alt}" update "${provider}" returned $?
+ eerror "eselect ${alt} update ${provider} returned $?"
;;
esac
done
}
-
-EXPORT_FUNCTIONS pkg_postinst pkg_prerm