aboutsummaryrefslogtreecommitdiff
blob: ff8129d9cc7ac4b65af063da8f376c1f4d42d971 (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# -*-eselect-*-  vim: ft=eselect
# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$

# This is a portage-only module.
inherit package-manager

DESCRIPTION="Manage the /etc/make.profile symlink"
MAINTAINER="eselect@gentoo.org"
SVN_DATE='$Date$'
VERSION=$(svn_date_to_version "${SVN_DATE}")

# get a list of valid profiles
find_targets() {
	local arch p portdir=${1}
	[[ -n ${portdir} ]] || portdir=$(portageq portdir)

	arch=$(arch)
	[[ -z ${arch} ]] && return 1

	for p in $(sed -n -e "s|^${arch}[[:space:]]\+\([^[:space:]]\+\).*$|\1|p" \
		"${ROOT}${portdir}/profiles/profiles.desc")
	do
		echo ${p}
	done
}

# remove make.profile symlink
remove_symlink() {
	rm "${EROOT}/etc/make.profile"
}

# set the make.profile symlink
set_symlink() {
	local portdir=$(portageq portdir) target=${1} targets arch parch

	if is_number "${target}" ; then
		targets=( $(find_targets "${portdir}") )
		[[ -z ${targets} ]] && die -q "Failed to get a list of valid profiles"
		target=${targets[target - 1]}
	elif [[ -n ${target} && -d ${ROOT}${portdir}/profiles/${target} ]]
	then
		# if the profile was explicitly specified (rather than a number)
		# double check and make sure it's valid
		arch=$(arch)
		[[ -z ${arch} && ${2} != "--force" ]] && return 1

		# do a reverse lookup and find the arch associated with ${target}
		parch=$(sed -n -e \
			"s|^\([[:alnum:]]\+\)[[:space:]].*${target}[[:space:]].*$|\1|p" \
			"${ROOT}${portdir}/profiles/profiles.desc")

		if [[ ${arch} != ${parch} && ${2} != "--force" ]] ; then
			die -q "${target} is not a valid profile for ${arch}"
		fi
	fi

	if [[ -z ${target} ]] ; then
		die -q "Target \"${1}\" doesn't appear to be valid!"
	elif [[ -d ${ROOT}${portdir}/profiles/${target} ]] ; then
		# we must call remove_symlink() here instead of calling
		# it from do_set(), since if the link is removed, we
		# cannot determine $ARCH in find_targets()
		if [[ -L ${EROOT}/etc/make.profile ]] ; then
			remove_symlink \
				|| die -q "Couldn't remove current make.profile symlink"
		fi
		ln -s "$(relative_name \
			"${ROOT}${portdir}" "${EROOT}/etc")/profiles/${target}" \
			"${EROOT}/etc/make.profile"
		# check if the resulting symlink is sane
		if [[ $(canonicalise "${EROOT}/etc/make.profile") \
			!= "$(canonicalise "${EROOT}")"/* ]]; then
			write_warning_msg \
				"Strange path. Check ${EROOT}/etc/make.profile symlink"
		fi
	else
		die -q "Target \"${1}\" doesn't appear to be valid!"
	fi
}

### show action ###

describe_show() {
	echo "Show the current make.profile symlink"
}

do_show() {
	write_list_start "Current make.profile symlink:"
	if [[ -L ${EROOT}/etc/make.profile ]] ; then
		local link=$(canonicalise "${EROOT}/etc/make.profile")
		local portdir=$(portageq portdir)
		local profiledir=$(canonicalise "${ROOT}${portdir}/profiles")
		link=${link##${profiledir}/}
		write_kv_list_entry "${link}" ""
	else
		write_kv_list_entry "(unset)" ""
	fi
}

### list action ###

describe_list() {
	echo "List available profile symlink targets"
}

do_list() {
	local portdir profiledir active targets
	targets=( $(find_targets) )

	[[ -z ${targets} ]] && die -q "Failed to get a list of valid profiles"

	portdir=$(portageq portdir)
	profiledir=$(canonicalise "${ROOT}${portdir}/profiles")
	active=$(canonicalise "${EROOT}/etc/make.profile")
	active=${active##${profiledir}/}
	if [[ -n ${targets[@]} ]] ; then
		local i
		for (( i = 0 ; i < ${#targets[@]} ; i = i + 1 )) ; do
			[[ ${targets[i]} == ${active} ]] \
				&& targets[i]=$(highlight_marker "${targets[i]}")
		done
	fi
	write_list_start "Available profile symlink targets:"
	write_numbered_list "${targets[@]}"
}

### set action ###

describe_set() {
	echo "Set a new profile symlink target"
}

describe_set_parameters() {
	echo "<target>"
}

describe_set_options() {
	echo "target : Target name or number (from 'list' action)"
	echo "--force : Forcibly set the symlink"
}

do_set() {
	local force

	if [[ ${1} == "--force" ]] ; then
		force=${1}
		shift
	fi

	if [[ -z ${1} ]] ; then
		die -q "You didn't tell me what to set the symlink to"
	elif [[ -e ${EROOT}/etc/make.profile ]] &&
		[[ ! -L ${EROOT}/etc/make.profile ]] ; then
		die -q "${EROOT}/etc/make.profile isn't a symlink"
	else
		set_symlink "${1}" ${force} || die -q "Couldn't set a new symlink"
	fi
}