summaryrefslogtreecommitdiff
blob: f1596bf977f34f7be37bd39228bfb0a27de47b58 (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
# Copyright 1999-2003 Gentoo Technologies, Inc.
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/eclass/alternatives.eclass,v 1.3 2003/10/07 20:28:52 liquidx Exp $

# Author :     Alastair Tse <liquidx@gentoo.org> (03 Oct 2003)
# Short Desc:  Creates symlink to the latest version of multiple slotted
#              packages.
#
# Long Desc:
#
#  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 if 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.
# 
ECLASS="alternatives"
INHERITED="$INHERITED $ECLASS"

# automatic deduction based on a symlink and a regex mask
alternatives_auto_makesym() {
	local SOURCE REGEX ALT
	local unsorted
	SOURCE=$1
	REGEX=$2

	ALT="`ls -1 --color=never ${ROOT}${REGEX} | sed -e "s:^${ROOT}::" | sort -r | xargs`"
	if [ -n "${ALT}" ]; then
		alternatives_makesym ${SOURCE} ${ALT}
	else
		eerror "regex ${REGEX} doesn't match any files."
	fi		
}

alternatives_makesym() {
	local ALTERNATIVES=""
	local SOURCE=""
	
	# usage: alternatives_makesym <resulting symlink> [alternative targets..]
	SOURCE=$1
	shift
	ALTERNATIVES=$@

	# step through given alternatives from first to last
	# and if one exists, link it and finish.
	
	for alt in ${ALTERNATIVES}; do
		if [ -f "${ROOT}${alt}" ]; then
			if [ -L "${ROOT}${SOURCE}" ]; then
				rm -f ${ROOT}${SOURCE}
			fi
			einfo "Linking ${alt} to ${SOURCE}"
			# we do this instead of ${ROOT}${SOURCE} because if
			# ROOT=/, then a symlink to //usr/bin/python confuses distutils
			cd ${ROOT}; ln -s ${alt} ${SOURCE}
			break
		fi
	done
	
	# report any errors
	if [ ! -L ${ROOT}${SOURCE} ]; then
		ewarn "Unable to establish ${SOURCE} symlink"
	elif [ ! -f "`readlink ${ROOT}${SOURCE}`" -a ! -f "${ROOT}`readlink ${ROOT}${SOURE}`" ]; then
		ewarn "${SOURCE} is a dead symlink."
	fi		
}		

alternatives_pkg_postinst() {
	if [ -n "${ALTERNATIVES}" -a -n "${SOURCE}" ]; then
		alternatives_makesym ${SOURCE} ${ALTERNATIVES}
	fi		
}

alternatives_pkg_postrm() {
	if [ -n "${ALTERNATIVES}" -a -n "${SOURCE}" ]; then
		alternatives_makesym ${SOURCE} ${ALTERNATIVES}
	fi
}

EXPORT_FUNCTIONS pkg_postinst pkg_postrm