1 |
# Copyright 1999-2013 Gentoo Foundation |
2 |
# Distributed under the terms of the GNU General Public License v2 |
3 |
# $Header: /var/cvsroot/gentoo-x86/eclass/alternatives.eclass,v 1.17 2011/08/22 04:46:31 vapier Exp $ |
4 |
|
5 |
# @ECLASS: alternatives.eclass |
6 |
# @AUTHOR: |
7 |
# Original author: Alastair Tse <liquidx@gentoo.org> (03 Oct 2003) |
8 |
# @BLURB: Creates symlink to the latest version of multiple slotted packages. |
9 |
# @DESCRIPTION: |
10 |
# When a package is SLOT'ed, very often we need to have a symlink to the |
11 |
# latest version. However, depending on the order the user has merged them, |
12 |
# more often than not, the symlink maybe clobbered by the older versions. |
13 |
# |
14 |
# This eclass provides a convenience function that needs to be given a |
15 |
# list of alternatives (descending order of recent-ness) and the symlink. |
16 |
# It will choose the latest version it can find installed and create |
17 |
# the desired symlink. |
18 |
# |
19 |
# There are two ways to use this eclass. First is by declaring two variables |
20 |
# $SOURCE and $ALTERNATIVES where $SOURCE is the symlink to be created and |
21 |
# $ALTERNATIVES is a list of alternatives. Second way is the use the function |
22 |
# alternatives_makesym() like the example below. |
23 |
# @EXAMPLE: |
24 |
# pkg_postinst() { |
25 |
# alternatives_makesym "/usr/bin/python" "/usr/bin/python2.3" "/usr/bin/python2.2" |
26 |
# } |
27 |
# |
28 |
# The above example will create a symlink at /usr/bin/python to either |
29 |
# /usr/bin/python2.3 or /usr/bin/python2.2. It will choose python2.3 over |
30 |
# python2.2 if both exist. |
31 |
# |
32 |
# Alternatively, you can use this function: |
33 |
# |
34 |
# pkg_postinst() { |
35 |
# alternatives_auto_makesym "/usr/bin/python" "/usr/bin/python[0-9].[0-9]" |
36 |
# } |
37 |
# |
38 |
# This will use bash pathname expansion to fill a list of alternatives it can |
39 |
# link to. It is probably more robust against version upgrades. You should |
40 |
# consider using this unless you are want to do something special. |
41 |
|
42 |
# @ECLASS-VARIABLE: SOURCE |
43 |
# @DEFAULT_UNSET |
44 |
# @DESCRIPTION: |
45 |
# The symlink to be created |
46 |
|
47 |
# @ECLASS-VARIABLE: ALTERNATIVES |
48 |
# @DEFAULT_UNSET |
49 |
# @DESCRIPTION: |
50 |
# The list of alternatives |
51 |
|
52 |
# @FUNCTION: alternatives_auto_makesym |
53 |
# @DESCRIPTION: |
54 |
# automatic deduction based on a symlink and a regex mask |
55 |
alternatives_auto_makesym() { |
56 |
has "${EAPI:-0}" 0 1 2 && ! use prefix && EROOT="${ROOT}" |
57 |
local SYMLINK REGEX ALT myregex |
58 |
SYMLINK=$1 |
59 |
REGEX=$2 |
60 |
if [ "${REGEX:0:1}" != "/" ] |
61 |
then |
62 |
#not an absolute path: |
63 |
#inherit the root directory of our main link path for our regex search |
64 |
myregex="${SYMLINK%/*}/${REGEX}" |
65 |
else |
66 |
myregex=${REGEX} |
67 |
fi |
68 |
|
69 |
# sort a space delimited string by converting it to a multiline list |
70 |
# and then run sort -r over it. |
71 |
# make sure we use ${EROOT} because otherwise stage-building will break |
72 |
ALT="$(for i in $(echo ${EROOT}${myregex}); do echo ${i#${EROOT}}; done | sort -r)" |
73 |
alternatives_makesym ${SYMLINK} ${ALT} |
74 |
} |
75 |
|
76 |
alternatives_makesym() { |
77 |
has "${EAPI:-0}" 0 1 2 && ! use prefix && EPREFIX= |
78 |
local ALTERNATIVES="" |
79 |
local SYMLINK="" |
80 |
local alt pref |
81 |
|
82 |
# usage: alternatives_makesym <resulting symlink> [alternative targets..] |
83 |
# make sure it is in the prefix, allow it already to be in the prefix |
84 |
SYMLINK=${EPREFIX}/${1#${EPREFIX}} |
85 |
# this trick removes the trailing / from ${ROOT} |
86 |
pref=${ROOT%/} |
87 |
shift |
88 |
ALTERNATIVES=$@ |
89 |
|
90 |
# step through given alternatives from first to last |
91 |
# and if one exists, link it and finish. |
92 |
|
93 |
for alt in ${ALTERNATIVES}; do |
94 |
alt=${EPREFIX}/${alt#${EPREFIX}} |
95 |
if [ -f "${pref}${alt}" ]; then |
96 |
#are files in same directory? |
97 |
if [ "${alt%/*}" = "${SYMLINK%/*}" ] |
98 |
then |
99 |
#yes; strip leading dirname from alt to create relative symlink |
100 |
einfo "Linking ${alt} to ${pref}${SYMLINK} (relative)" |
101 |
ln -sf ${alt##*/} ${pref}${SYMLINK} |
102 |
else |
103 |
#no; keep absolute path |
104 |
einfo "Linking ${alt} to ${pref}${SYMLINK} (absolute)" |
105 |
ln -sf ${pref}${alt} ${pref}${SYMLINK} |
106 |
fi |
107 |
break |
108 |
fi |
109 |
done |
110 |
|
111 |
# report any errors |
112 |
if [ ! -L ${pref}${SYMLINK} ]; then |
113 |
ewarn "Unable to establish ${pref}${SYMLINK} symlink" |
114 |
else |
115 |
# we need to check for either the target being in relative path form |
116 |
# or absolute path form |
117 |
if [ ! -f "`dirname ${pref}${SYMLINK}`/`readlink ${pref}${SYMLINK}`" -a \ |
118 |
! -f "`readlink ${pref}${SYMLINK}`" ]; then |
119 |
ewarn "Removing dead symlink ${pref}${SYMLINK}" |
120 |
rm -f ${pref}${SYMLINK} |
121 |
fi |
122 |
fi |
123 |
} |
124 |
|
125 |
# @FUNCTION: alernatives-pkg_postinst |
126 |
# @DESCRIPTION: |
127 |
# The alternatives pkg_postinst, this function will be exported |
128 |
alternatives_pkg_postinst() { |
129 |
if [ -n "${ALTERNATIVES}" -a -n "${SOURCE}" ]; then |
130 |
alternatives_makesym ${SOURCE} ${ALTERNATIVES} |
131 |
fi |
132 |
} |
133 |
|
134 |
# @FUNCTION: alternatives_pkg_postrm |
135 |
# @DESCRIPTION: |
136 |
# The alternatives pkg_postrm, this function will be exported |
137 |
alternatives_pkg_postrm() { |
138 |
if [ -n "${ALTERNATIVES}" -a -n "${SOURCE}" ]; then |
139 |
alternatives_makesym ${SOURCE} ${ALTERNATIVES} |
140 |
fi |
141 |
} |
142 |
|
143 |
EXPORT_FUNCTIONS pkg_postinst pkg_postrm |