aboutsummaryrefslogtreecommitdiff
blob: 4fcf672952210276b507245cfc04b354c1e8abe2 (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
# Copyright 2010-2015 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-2_pkg_{postinst,prerm} where appropriate.

case "${EAPI:-0}" in
	0|1|2|3|4)
		die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
		;;
	5)
		;;
	*)
		die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
		;;
esac

DEPEND=">=app-admin/eselect-1.4.4-r102"
RDEPEND="${DEPEND}
	!app-admin/eselect-blas
	!app-admin/eselect-cblas
	!app-admin/eselect-lapack"

# @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 sh bash 0 \
#     /usr/bin/sh bash
# @CODE
alternatives_for() {
	debug-print-function ${FUNCNAME} "${@}"

	dodir /etc/env.d/alternatives

	ALTERNATIVESDIR_ROOTLESS="${ED}/etc/env.d/alternatives" \
		eselect alternatives add ${@} || die

	ALTERNATIVES_CREATED+=( ${1} )
}

# @FUNCTION: cleanup_old_alternatives_module
# @USAGE: <alternative>
# @DESCRIPTION:
# Remove old alternatives module.
cleanup_old_alternatives_module() {
	debug-print-function ${FUNCNAME} "${@}"

	local alt=${1} old_module="${EROOT%/}/usr/share/eselect/modules/${alt}.eselect"

	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
			einfo "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() {
	debug-print-function ${FUNCNAME} "${@}"

	local alt

	for alt in ${ALTERNATIVES_CREATED[@]}; do
		if ! eselect ${alt} show > /dev/null; then
			einfo "Creating Alternative for ${alt}"
			eselect alternatives create ${alt}
		fi

		# 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 alternative when last
# provider is unmerged.
#
# Provided alternatives are set up using alternatives_for().
alternatives-2_pkg_prerm() {
	debug-print-function ${FUNCNAME} "${@}"

	local alt ret

	# If we are uninstalling, update alternatives to valid provider
	[[ -n ${REPLACED_BY_VERSION} ]] || ignore="--ignore"

	for alt in ${ALTERNATIVES_CREATED[@]}; do
		eselect "${alt}" update ${ignore} "${provider}"

		case ${ret} in
			0) : ;;
			2)
				# This was last provider for the alternative, remove eselect module
				einfo "Cleaning up unused alternatives module for ${alt}"
				eselect alternatives delete "${alt}" || eerror "Failed to remove ${alt}"
				;;
			*)
				eerror "eselect ${alt} update ${provider} returned ${ret}"
				;;
		esac
	done
}

EXPORT_FUNCTIONS pkg_postinst pkg_prerm