# -*-eselect-*- vim: ft=eselect # Copyright 1999-2011 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: profile.eselect 820 2011-07-07 18:03:44Z ulm $ # This is a portage-only module. inherit package-manager DESCRIPTION="Manage the make.profile symlink" MAINTAINER="eselect@gentoo.org" SVN_DATE='$Date: 2011-07-07 20:03:44 +0200 (Thu, 07 Jul 2011) $' VERSION=$(svn_date_to_version "${SVN_DATE}") # get location of make.profile symlink get_symlink_location() { local oldloc=${EROOT%/}/etc/make.profile local newloc=${EROOT%/}/etc/portage/make.profile if [[ -e ${oldloc} ]]; then MAKE_PROFILE=${oldloc} if [[ -e ${newloc} ]]; then write_warning_msg "Both ${oldloc} and ${newloc} exist." write_warning_msg "Using ${MAKE_PROFILE} for now." fi else MAKE_PROFILE=${newloc} fi } # get a list of valid profiles find_targets() { # declaring local arrays local -a repos=( $( portageq get_repos "/" ) ) repospaths=( $( portageq get_repo_path "/" ${repos[@]} ) ) # declaring local vars local arch=$( arch ) reposnum=${#repos[@]} repospathsnum=${#repospaths[@]} reponum p; # empty $arch & $repos leads to north-north-west^Wexit [[ -z ${arch} ]] && [[ -z ${repos} ]] && { echo "Errorr: cannot determine arch and repos">/dev/stderr; return 1; } # Portageq sanity check: $reposnum & $repospathsnum must be equal [[ "${reposnum}" != "${repospathsnum}" ]] && { echo "Errorr: unexpected portageq answer">/dev/stderr; return 1; } for(( reponum=0; $reponum<$reposnum; reponum++ ));do [[ -r ${ROOT}/${repospaths[$reponum]}/profiles/profiles.desc ]] && \ # parsing profiles.desc for $arch suitable profiles for p in $( sed -n -e \ "s|^${arch}[[:space:]]\+\([^[:space:]]\+\).*$|${repos[$reponum]}:\1|p" "${ROOT}${repospaths[$reponum]}/profiles/profiles.desc" ); # printing "overlay-name:profile-dir" pairs do echo ${p}; done done } # remove make.profile symlink remove_symlink() { rm "${MAKE_PROFILE}" } # set the make.profile symlink set_symlink() { local portdir=$(portageq portdir) target=${1} force=${2} arch=$( arch ) parch repo repo_path [[ -z ${target} ]] && die -q "Target \"${1}\" doesn't appear to be valid!" local -a targets=( $(find_targets ) ) [[ -z ${targets} ]] && die -q "Failed to get a list of valid profiles" if is_number "${target}" ; then target=${targets[target - 1]}; fi repo=${target%:*} repopath=$( portageq get_repo_path / ${repo} ) target=${target#*:} if [[ -n ${target} && -d ${ROOT}${repopath}/profiles/${target} ]];then # if the profile was explicitly specified (rather than a number) # double check and make sure it's valid [[ -z ${arch} && -z "${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}${repopath}/profiles/profiles.desc") if [[ ${arch} != ${parch} && -z "${force}" ]] ; then die -q "${target} is not a valid profile for ${arch}" fi fi if [[ -d ${ROOT}${repopath}/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 # set relative symlink ln -s "$(relative_name "${EROOT}${repopath}/profiles/${target}" "${EROOT}/etc")" "${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 at all!" fi } ### show action ### describe_show() { echo "Show the current make.profile symlink" } do_show() { get_symlink_location write_list_start "Current ${MAKE_PROFILE} symlink:" if [[ -L ${MAKE_PROFILE} ]]; then local link=$(canonicalise "${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" get_symlink_location portdir=$(portageq portdir) profiledir=$(canonicalise "${ROOT}${portdir}/profiles") active=$(canonicalise "${MAKE_PROFILE}") active=${active##${profiledir}/} if [[ -n ${targets[@]} ]]; then local i for (( i = 0; i < ${#targets[@]}; i++ )); 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 "" } 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 [[ -z $1 ]] && die -q "You didn't tell me what to set the symlink to" [[ $# -gt 1 ]] && die -q "Too many parameters" get_symlink_location if [[ -e ${MAKE_PROFILE} ]] && [[ ! -L ${MAKE_PROFILE} ]]; then die -q "${MAKE_PROFILE} exists but is not a symlink" else set_symlink "$1" ${force} || die -q "Couldn't set a new symlink" fi }