aboutsummaryrefslogtreecommitdiff
path: root/rpath.sh
diff options
context:
space:
mode:
Diffstat (limited to 'rpath.sh')
-rwxr-xr-xrpath.sh168
1 files changed, 168 insertions, 0 deletions
diff --git a/rpath.sh b/rpath.sh
new file mode 100755
index 0000000..ea84d21
--- /dev/null
+++ b/rpath.sh
@@ -0,0 +1,168 @@
+#!/usr/bin/env bash
+#
+# Copyright 2014 David Vazgenovich Shakaryan
+# Distributed under the terms of the MIT License.
+#
+# rpath
+# https://github.com/omp/rpath
+# Manage multiple Ruby installations with no black magic.
+#
+# In order to prevent environment pollution, the output of this script
+# is a list of commands which must be sourced. This can be achieved
+# through a simple shell function:
+#
+# rpath() { source <(/path/to/rpath.sh "${@}"); }
+#
+# Two methods of version matching are supported. If the specified
+# argument consists of only numbers, it is matched against the list
+# number shown in `rpath ls`. Otherwise, a substring match is performed
+# against the directory name.
+
+: ${RUBIES_PATH:="${HOME}/.rubies"}
+
+_echo() {
+ echo "echo '${@//\'/\'\\\'\'}'"
+}
+
+_export_path() {
+ echo "export PATH='${PATH//\'/\'\\\'\'}'"
+ echo "hash -r"
+}
+
+_die() {
+ [[ -n "${@}" ]] && echo "echo '${@//\'/\'\\\'\'}' 1>&2"
+
+ echo "false"
+ exit 1
+}
+
+_populate_dirs() {
+ [[ -d "${RUBIES_PATH}" ]] \
+ || _die "Directory ${RUBIES_PATH} does not exist."
+
+ # Cannot handle paths containing a newline. Only an idiot would
+ # encounter this in practice.
+ readarray -t dirs < \
+ <(printf '%s\0' "${RUBIES_PATH}"/* | sort -zV | xargs -0n1)
+}
+
+_match() {
+ if [[ "${1}" =~ ^[0-9]+$ ]]; then
+ [[ "${2}" == "${1}" ]] && return
+ else
+ [[ "${3}" == *"${1}"* ]] && return
+ fi
+
+ return 1
+}
+
+_get() {
+ local dir dirs succeed=false
+
+ IFS=':' read -a dirs <<< "${PATH}"
+
+ for dir in "${dirs[@]}"; do
+ if [[ "${dir}" == "${RUBIES_PATH}/"* ]]; then
+ dir="${dir%/bin}"
+ echo "${dir##*/}"
+
+ succeed=true
+ fi
+ done
+
+ $succeed || return 1
+}
+
+_set() {
+ _clear
+ _echo "Adding ${1}/bin to PATH."
+
+ PATH="${1}/bin:${PATH}"
+}
+
+_clear() {
+ local dir dirs cdirs=() succeed=false
+
+ IFS=':' read -a dirs <<< "${PATH}"
+
+ for dir in "${dirs[@]}"; do
+ if [[ "${dir}" == "${RUBIES_PATH}/"* ]]; then
+ _echo "Removing ${dir} from PATH."
+
+ succeed=true
+ else
+ cdirs+=("${dir}")
+ fi
+ done
+
+ $succeed || return 1
+
+ PATH="$(IFS=':'; echo "${cdirs[*]}")"
+}
+
+rpath_ls() {
+ _populate_dirs
+
+ counter=0
+ current=$(_get | head -n 1)
+
+ for dir in "${dirs[@]}"; do
+ str="[$((++counter))] ${dir##*/}"
+
+ [[ "${dir##*/}" == "${current}" ]] && str+=" *"
+
+ _echo "${str}"
+ done
+}
+
+rpath_get() {
+ current="$(_get)" && _echo "${current}"
+}
+
+rpath_set() {
+ [[ -z "${1}" ]] && _die 'rpath set requires an argument.'
+
+ _populate_dirs
+
+ counter=0
+
+ for dir in "${dirs[@]}"; do
+ if _match "${1}" "$((++counter))" "${dir##*/}"; then
+ _set "${dir}"
+ _export_path
+
+ return
+ fi
+ done
+
+ _die 'No matching ruby found.'
+}
+
+rpath_clear() {
+ _clear || _die 'No rubies found in PATH.'
+ _export_path
+}
+
+rpath_help() {
+ _echo 'Usage: rpath <command> [args]'
+ _echo
+ _echo 'Available options:'
+ _echo ' ls List all available rubies.'
+ _echo ' get Display currently selected ruby.'
+ _echo ' set Select specified ruby.'
+ _echo ' clear Clear path of any rpath rubies.'
+ _echo ' help Display this help information.'
+}
+
+case "${1}" in
+ 'ls')
+ rpath_ls ;;
+ 'get')
+ rpath_get ;;
+ 'set')
+ rpath_set "${2}" ;;
+ 'clear')
+ rpath_clear ;;
+ *)
+ rpath_help ;;
+esac