# -*-eselect-*- vim: ft=eselect
# Copyright (c) 2006-2012 Gentoo Foundation
# $Id$
# This file is part of the 'eselect' tools framework.
#
# eselect is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 2 of the License, or (at your option) any later
# version.
#
# eselect is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# eselect. If not, see .
# To use this library, you must set MODULE and IFACE.
# MODULE is the name you use to refer to whatever it is that you're selecting
# in help text and so forth.
# IFACE is the subdirectory of /etc/env.d/ that eselect config files are stored
# in for these packages.
#
# There is a file installed at /etc/env.d/$IFACE/$libdir/config containing the
# CURRENT variable, which is set to the current eselect setting. Also, each
# implementation installs a single file at /etc/env.d/$IFACE/$libdir/$implem.
# This file contains a list of symlinks to be created in "source destination"
# format. You must use relative symlinks. In other words, "source" must be
# relative to "destination" but "destination" must be absolute. You may have
# comments in the symlink map file -- any line containing a '#' is considered
# a comment. One caveat about the symlink map -- instead of using "lib" or
# "lib64" etc, you must use @LIBDIR@.
inherit config multilib tests
# find_implems $iface $libdir
# find all possible implems for $libdir
find_implems() {
local -a implems
local confdir=${EROOT}/etc/env.d/${iface}/${libdir}
iface=$1 libdir=$2
for file in "${confdir}"/* ; do
[[ -f ${file} ]] || continue
[[ "${file##*/}" != "config" ]] || continue
implems=(${implems[@]} "${file##*/}")
done
echo ${implems[@]}
}
# is_active $iface $libdir $implem
# returns true if $implem is currently used for the $iface/$libdir combination
is_active() {
[[ $# -eq 3 ]] || die "Need exactly 3 arguments!"
current=$(load_config "${EROOT}/etc/env.d/${1}/${2}/config" CURRENT)
[[ ${current} == ${3} ]]
}
# switch_implem $iface $libdir $implem
# switches $iface/$libdir combination to $implem
switch_implem() {
# set us up
[[ $# -eq 3 ]] || die "Need exactly 3 arguments!"
local iface=${1}
local libdir=${2}
local implem=${3##*/}
local confdir=${EROOT}/etc/env.d/${iface}/${libdir}
local current=$(load_config "${confdir}/config" CURRENT)
local dest src
# Get rid of old symlinks, if we have a current config
if [[ -f ${confdir}/${current} ]]; then
while read line; do
# Skip comments
[[ "${line}" = *#* ]] && continue
line=${line//@LIBDIR@/${libdir}}
set ${line}
dest=$2
rm -f "${ROOT}${dest}"
done < "${confdir}/${current}"
fi
# Set up new symlinks
while read line; do
# Skip comments
[[ "${line}" = *#* ]] && continue
line=${line//@LIBDIR@/${libdir}}
set ${line}
src=$1
dest=$2
ln -sf "${src}" "${ROOT}${dest}"
done < "${confdir}/${implem}"
store_config "${confdir}/config" CURRENT ${implem}
}
# iface_do_list $libdir
# Lists the available implementations for $libdir
iface_do_list() {
local -a implems
local libdir=$1 iface=$IFACE
implems=( $(find_implems $iface $libdir ) )
# None installed for $libdir
[[ -z ${implems[@]} ]] \
&& return
write_list_start "Installed $MODULE for library directory $(highlight ${libdir})"
for implem in ${implems[@]} ; do
(( i++ ))
is_active ${iface} ${libdir} ${implem##*/} \
&& implem=$(highlight_marker "${implem}")
write_numbered_list_entry $i "${implem}"
done
}
# iface_do_show $libdir
# Shows the current implementation for $libdir
iface_do_show() {
local iface=$IFACE libdir=$1 implem
local confdir=${EROOT}/etc/env.d/${iface}/${libdir}
[[ -e ${confdir}/config ]] || return
implem=$(load_config "${confdir}/config" CURRENT)
[[ -e ${confdir}/${implem} ]] \
|| die "File \"${confdir}/${implem}\" is missing!"
echo "${libdir}: ${implem}"
}
# get_libdirs
# Wraps list_libdirs() to ensure that output is sorted consistently
get_libdirs() {
list_libdirs | sort
}
### list action
describe_list() {
echo "List all installed $MODULE implementations"
}
do_list() {
local libdir
# Count for listing IFACE/libdir combinations
# We keep it here so it doesn't reset on every call to iface_do_list()
local i=0
for libdir in $(get_libdirs); do
[[ -d ${EROOT}/usr/${libdir} && ! -L ${EROOT}/usr/${libdir} ]] \
&& iface_do_list $libdir
done
}
### set action
describe_set() {
echo "Activate one of the installed $MODULE implementations"
}
describe_set_parameters() {
echo ""
}
describe_set_options() {
echo "implementation : implementation name or number (from 'list' action)"
}
do_set() {
[[ $# -eq 0 ]] && die -q "Please specify exactly 1 implementation!"
local fail=0 iface=$IFACE
local libdirs=$(get_libdirs)
local libdir implem libdir_ct i=0
local -a file implems new_implems mylibdirs myimplems
# Build up list of all valid implems
for libdir in ${libdirs}; do
new_implems=( $(find_implems ${iface} ${libdir}) )
implems=( ${implems[@]} ${new_implems[@]} )
libdir_ct[$i]=${#new_implems[@]}
(( i++ ))
done
# Parse passed parameters into valid libdirs. Other arguments are considered
# implementations (or numbers for them) and are validated later.
# If libdirs are specified, then switch for them. Otherwise, switch for all
# libdirs.
for param in ${@} ; do
if has ${param} ${libdirs} ; then
mylibdirs=(${mylibdirs[@]} ${param})
else
myimplems=(${myimplems[@]} ${param})
fi
done
set ${myimplems[@]}
# We can only change one implem at a time
[[ ${#myimplems[@]} -ne 1 ]] && \
die -q "Please specify exactly 1 implemention."
[[ -n ${mylibdirs[@]} ]] && libdirs=${mylibdirs[@]}
i=0
for libdir in ${libdirs}; do
# Only move on if we actually have implems here, otherwise we screw up
# $libdir_max and waste time executing pointless code
if [[ ${libdir_ct[$i]} -gt 0 ]]; then
for item in ${@} ; do
if is_number ${item} ; then
# On the first libdir, minimum must be 1. Maxes and later
# mins are incremented by the size of the previous libdir_ct
if [[ -n ${libdir_min} ]]; then
libdir_min=$(( ${libdir_min} + ${libdir_ct[$(( $i - 1 ))]} ))
else
libdir_min="1"
fi
libdir_max=$(( ${libdir_min} + ${libdir_ct[$i]} - 1 ))
if [[ ${item} -ge ${libdir_min} ]] && [[ ${item} -le ${libdir_max} ]] ; then
if ! switch_implem ${iface} ${libdir} ${implems[$(( ${item} -1 ))]}; then
fail=1
echo "Failed to switch to implementation \"${item}\" for library directory \"${libdir}\"!"
continue
fi
else
fail=1
echo "Item not in range ${libdir_min}-${libdir_max} for ${libdir}: ${item}"
continue
fi
else
# Only attempt to switch to an implementation if it's available
# for that libdir
if has ${item} $(find_implems ${iface} ${libdir}); then
if ! switch_implem ${iface} ${libdir} ${item}; then
fail=1
echo "Failed to switch to implementation \"${item}\" for library directory \"${libdir}\"!"
continue
fi
fi
fi
done
fi
(( i++ ))
done
[[ ${fail} == 1 ]] && die -q "One or more actions have failed!"
}
### show action
describe_show() {
echo "Print the currently active $MODULE implementation"
}
do_show() {
local libdir
local libdirs=$(get_libdirs)
for param in ${@} ; do
if has ${param} ${libdirs} ; then
mylibdirs=(${mylibdirs[@]} ${param})
fi
done
[[ -n ${mylibdirs[@]} ]] && libdirs=${mylibdirs[@]}
for libdir in ${libdirs}; do
[[ -d ${EROOT}/usr/${libdir} && ! -L ${EROOT}/usr/${libdir} ]] \
&& iface_do_show $libdir
done
}
### add action
describe_add() {
echo "Add a new $MODULE implementation"
}
describe_add_parameters() {
echo " "
}
describe_add_options() {
echo "libdir : library directory where $MODULE implementation is installed (lib, lib64, etc.)"
echo "file : path to file containing symlink map"
echo "implementation : name of the $MODULE implementation"
}
do_add() {
[[ $# -eq 3 ]] \
|| die -q "Please specify 1 library directory, 1 file to install and 1 implementation!"
# If $D is set, we're adding from portage so we want to respect sandbox.
# Otherwise, respect the ROOT variable.
local prefix=${D:-${ROOT}}${EPREFIX}
# Create directory if necessary
if [[ ! -e ${prefix}/etc/env.d/${IFACE}/${1} ]]; then
mkdir -p "${prefix}/etc/env.d/${IFACE}/${1}"
elif [[ ! -d ${prefix}/etc/env.d/${IFACE}/${1} ]]; then
die -q "${prefix}/etc/env.d/${IFACE}/${1} exists but isn't a directory!"
fi
if ! cp "${2}" "${prefix}/etc/env.d/${IFACE}/${1}/${3}"; then
die -q "Installing ${2} as ${prefix}/etc/env.d/${IFACE}/${1}/${3} failed!"
fi
}