forked from gentoo/gentoo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
alternatives.eclass
156 lines (140 loc) · 4.78 KB
/
alternatives.eclass
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
# Copyright 1999-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: alternatives.eclass
# @MAINTAINER:
# @AUTHOR:
# Alastair Tse <[email protected]> (03 Oct 2003)
# @SUPPORTED_EAPIS: 5 6 7
# @BLURB: Creates symlink to the latest version of multiple slotted packages.
# @DESCRIPTION:
# When a package is SLOT'ed, very often we need to have a symlink to the
# latest version. However, depending on the order the user has merged them,
# more often than not, the symlink maybe clobbered by the older versions.
#
# This eclass provides a convenience function that needs to be given a
# list of alternatives (descending order of recent-ness) and the symlink.
# It will choose the latest version it can find installed and create
# the desired symlink.
#
# There are two ways to use this eclass. First is by declaring two variables
# $SOURCE and $ALTERNATIVES where $SOURCE is the symlink to be created and
# $ALTERNATIVES is a list of alternatives. Second way is the use the function
# alternatives_makesym() like the example below.
# @EXAMPLE:
# pkg_postinst() {
# alternatives_makesym "/usr/bin/python" "/usr/bin/python2.3" "/usr/bin/python2.2"
# }
#
# The above example will create a symlink at /usr/bin/python to either
# /usr/bin/python2.3 or /usr/bin/python2.2. It will choose python2.3 over
# python2.2 if both exist.
#
# Alternatively, you can use this function:
#
# pkg_postinst() {
# alternatives_auto_makesym "/usr/bin/python" "/usr/bin/python[0-9].[0-9]"
# }
#
# This will use bash pathname expansion to fill a list of alternatives it can
# link to. It is probably more robust against version upgrades. You should
# consider using this unless you are want to do something special.
case ${EAPI} in
[5-7]) ;;
*) die "EAPI=${EAPI:-0} is not supported" ;;
esac
EXPORT_FUNCTIONS pkg_postinst pkg_postrm
if [[ -z ${_ALTERNATIVES_ECLASS} ]]; then
_ALTERNATIVES_ECLASS=1
# @ECLASS_VARIABLE: SOURCE
# @DEFAULT_UNSET
# @DESCRIPTION:
# The symlink to be created
# @ECLASS_VARIABLE: ALTERNATIVES
# @DEFAULT_UNSET
# @DESCRIPTION:
# The list of alternatives
# @FUNCTION: alternatives_auto_makesym
# @DESCRIPTION:
# Automatic deduction (Bash pathname expansion) based on a symlink and a regex mask
alternatives_auto_makesym() {
local SYMLINK REGEX ALT myregex
SYMLINK=$1
REGEX=$2
if [ "${REGEX:0:1}" != "/" ]
then
#not an absolute path:
#inherit the root directory of our main link path for our regex search
myregex="${SYMLINK%/*}/${REGEX}"
else
myregex=${REGEX}
fi
# sort a space delimited string by converting it to a multiline list
# and then run sort -r over it.
# make sure we use ${EROOT} because otherwise stage-building will break
ALT="$(for i in $(echo ${EROOT}${myregex}); do echo ${i#${EROOT}}; done | sort -r)"
alternatives_makesym ${SYMLINK} ${ALT}
}
# @FUNCTION: alternatives_makesym
# @DESCRIPTION:
# Creates symlink based on a symlink and regex mask literally
alternatives_makesym() {
local ALTERNATIVES=""
local SYMLINK=""
local alt pref
# usage: alternatives_makesym <resulting symlink> [alternative targets..]
# make sure it is in the prefix, allow it already to be in the prefix
SYMLINK=${EPREFIX}/${1#${EPREFIX}}
# this trick removes the trailing / from ${ROOT}
pref=${ROOT%/}
shift
ALTERNATIVES=$@
# step through given alternatives from first to last
# and if one exists, link it and finish.
for alt in ${ALTERNATIVES}; do
alt=${EPREFIX}/${alt#${EPREFIX}}
if [ -f "${pref}${alt}" ]; then
#are files in same directory?
if [ "${alt%/*}" = "${SYMLINK%/*}" ]
then
#yes; strip leading dirname from alt to create relative symlink
einfo "Linking ${alt} to ${pref}${SYMLINK} (relative)"
ln -sf ${alt##*/} ${pref}${SYMLINK}
else
#no; keep absolute path
einfo "Linking ${alt} to ${pref}${SYMLINK} (absolute)"
ln -sf ${pref}${alt} ${pref}${SYMLINK}
fi
break
fi
done
# report any errors
if [ ! -L ${pref}${SYMLINK} ]; then
ewarn "Unable to establish ${pref}${SYMLINK} symlink"
else
# we need to check for either the target being in relative path form
# or absolute path form
if [ ! -f "`dirname ${pref}${SYMLINK}`/`readlink ${pref}${SYMLINK}`" -a \
! -f "`readlink ${pref}${SYMLINK}`" ]; then
ewarn "Removing dead symlink ${pref}${SYMLINK}"
rm -f ${pref}${SYMLINK}
fi
fi
}
# @FUNCTION: alternatives_pkg_postinst
# @DESCRIPTION:
# The alternatives pkg_postinst, this function will be exported
alternatives_pkg_postinst() {
if [ -n "${ALTERNATIVES}" -a -n "${SOURCE}" ]; then
alternatives_makesym ${SOURCE} ${ALTERNATIVES}
fi
}
# @FUNCTION: alternatives_pkg_postrm
# @DESCRIPTION:
# The alternatives pkg_postrm, this function will be exported
alternatives_pkg_postrm() {
if [ -n "${ALTERNATIVES}" -a -n "${SOURCE}" ]; then
alternatives_makesym ${SOURCE} ${ALTERNATIVES}
fi
}
fi