diff options
Diffstat (limited to 'rust.eselect.in')
-rw-r--r-- | rust.eselect.in | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/rust.eselect.in b/rust.eselect.in new file mode 100644 index 0000000..96fba74 --- /dev/null +++ b/rust.eselect.in @@ -0,0 +1,258 @@ +# Copyright 1999-2019 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +DESCRIPTION="Manage the Rust compiler versions" +MAINTAINER="rust@gentoo.org" +VERSION="@VERSION@" + +inherit package-manager path-manipulation + +# find a list of installed rust compilers +# each compiler provider should install +# a config file named provider-$pkgname-$pkgver +# in "${EROOT}"/etc/env.d/rust directory +# this function prints list of $pkgname-$pkgver values +find_targets() { + local f + local -a providers + for f in "${EROOT}"/etc/env.d/rust/provider-*; do + [[ -f ${f} ]] || continue + providers=("${providers[@]}" "${f##*/provider-}") + done + echo "${providers[@]}" +} + +#get rustc postfix +get_postfix() { + local target=$1 + echo "${target}" | cut -d- -f2- +} + +#get current target +get_current_target() { + local i targets=( $(find_targets) ) + for (( i = 0; i < ${#targets[@]}; i++ )); do + [[ rustc-$(get_postfix ${targets[i]}) = \ + $(basename "$(canonicalise "${EROOT}/usr/bin/rustc")") ]] \ + && echo $i && return 0 + done + echo "NOT_SET" +} + +#get symlinks list from file or the default value +get_symlinks_from_file() { + local filename=$1 + local symlinks=() + local i + if [[ -e ${filename} ]]; then + for i in `cat "${filename}"`; do + symlinks+=($i) + done + fi + + if [ ${#symlinks[@]} -eq 0 ]; then + echo /usr/bin/rustdoc + else + echo "${symlinks[@]}" + fi + +} + +#get last set symlinks +get_last_set_symlinks() { + local symlinks=( $(get_symlinks_from_file "${EROOT}/etc/env.d/rust/last-set") ) + echo "${symlinks[@]}" +} + +#get lists of symlinks +get_symlinks() { + local target=$1 + if [ "${target}" == "NOT_SET" ]; then + echo /usr/bin/rustdoc + return + fi + if is_number "${target}"; then + local targets=( $(find_targets) ) + target=${targets[target]} + fi + + local symlinks=( $(get_symlinks_from_file "${EROOT}/etc/env.d/rust/provider-${target}") ) + echo "${symlinks[@]}" +} + +# remove symlink if exists +remove_symlink() { + local symlink=$1 + + if [[ -L ${symlink} ]]; then + # existing symlink + rm ${symlink} || die -q "Couldn't remove existing symlink ${symlink}" + elif [[ -e ${symlink} ]]; then + # we have something strange + die -q "${symlink} exists but is not a symlink" + fi +} + +# set symlink if source exists +set_symlink() { + local source=$1 + local dest=$2 + + remove_symlink "${dest}" + + if [[ -e ${source} ]]; then + mkdir -p "$(dirname ${dest})" || die -q "directory creation failed for $(dirname ${dest})" + ln -s "${source}" "${dest}" || die -q "${dest} symlink setting failed" + else + false + fi +} + +# unset the rust version +unset_version() { + local symlinks=( $(get_last_set_symlinks) ) + for i in "${symlinks[@]}"; do + remove_symlink "${EROOT}${i}" + done + remove_symlink "${EROOT}/usr/bin/rustc" + rm -f "${EROOT}/etc/env.d/rust/last-set" \ + || die -q "rm -f ${EROOT}/etc/env.d/rust/last-set failed" +} + +# set the rust version +# each compiler provider should install +# files named rustc-$postfix and rustdoc-$postfix +# in ${EROOT}/usr/bin directory +# $postfix is defined as the part of $pkgname-$pkgver after the first - +# for dev-lang/rust-bin-9999 ebuild it would be bin-9999 +set_version() { + local target=$1 + + if is_number "${target}"; then + local targets=( $(find_targets) ) + target=${targets[target-1]} + fi + + target_postfix=$(get_postfix ${target}) + + [[ -z ${target_postfix} || ! -x "${EROOT}/usr/bin/rustc-${target_postfix}" ]] \ + && die -q "Target \"$1\" doesn't appear to be valid!" + + unset_version + + set_symlink "${EROOT}/usr/bin/rustc-${target_postfix}" "${EROOT}/usr/bin/rustc" + + local symlinks=( $(get_symlinks ${target}) ) + for i in "${symlinks[@]}"; do + set_symlink "${EROOT}${i}-${target_postfix}" "${EROOT}${i}" + done + + cp "${EROOT}/etc/env.d/rust/provider-${target}" \ + "${EROOT}/etc/env.d/rust/last-set" || \ + die -q "symlink list copying failed" +} + +### list action ### + +describe_list() { + echo "List available Rust versions" +} + +do_list() { + local i + local targets=( $(find_targets) ) + local target=$(get_current_target) + + if is_number "${target}"; then + targets[target]=$(highlight_marker "${targets[target]}") + fi + + write_list_start "Available Rust versions:" + write_numbered_list -m "(none found)" "${targets[@]}" +} + +### set action ### + +describe_set() { + echo "Set active Rust version" +} + +describe_set_parameters() { + echo "<target>" +} + +describe_set_options() { + echo "target : Target number (from 'list' action)" +} + +do_set() { + [[ -z $1 ]] && die -q "You didn't tell me what to set the version to" + [[ $# -gt 1 ]] && die -q "Too many parameters" + + set_version "$1" || die -q "Couldn't set new active version" +} + +### update action ### + +describe_update() { + echo "Switch to the most recent Rust compiler" +} + +describe_update_options() { + echo "--if-unset : Do not override existing implementation" +} + +do_update() { + local if_unset="0" + while [[ $# > 0 ]]; do + case "$1" in + --if-unset) + if_unset="1" + ;; + *) + die -q "Unrecognized argument '$1'" + ;; + esac + shift + done + + if [[ "${if_unset}" == "1" && -f "${EROOT}"/usr/bin/rustc ]]; then + return + fi + + local targets=( $(find_targets) ) + do_set ${#targets[@]} +} + +### unset action ### + +describe_unset() { + echo "Unset active Rust version" +} + +describe_unset_options() { + echo "--if-invalid : Unset only if symlink is invalid (e.g. package was uninstalled)" +} + +do_unset() { + local if_invalid="0" + while [[ $# > 0 ]]; do + case "$1" in + --if-invalid) + if_invalid="1" + ;; + *) + die -q "Unrecognized argument '$1'" + ;; + esac + shift + done + + if [[ "${if_invalid}" == "1" && -e "${EROOT}"/usr/bin/rustc ]]; then + return + fi + + unset_version || die -q "Couldn't unset active version" +} + +# vim: set ft=eselect : |