diff --git a/share/chruby/chruby.sh b/share/chruby/chruby.sh index 29e6b243..b7498d12 100644 --- a/share/chruby/chruby.sh +++ b/share/chruby/chruby.sh @@ -1,10 +1,55 @@ CHRUBY_VERSION="0.3.9" -RUBIES=() -for dir in "$PREFIX/opt/rubies" "$HOME/.rubies"; do - [[ -d "$dir" && -n "$(ls -A "$dir")" ]] && RUBIES+=("$dir"/*) -done -unset dir +function chruby_list_rubies() +{ + local chruby_entry + for chruby_entry in "$@"; do + [[ -x "$chruby_entry/bin/ruby" ]] && echo "$chruby_entry" + done +} + +function chruby_detect_rubies() +{ + if [[ -d "$1" ]]; then + { chruby_list_rubies "$1"/* ;} 2>/dev/null || true + else + chruby_list_rubies $1 + fi +} + +function chruby_stable_version_sort() { + local dir last_engine ruby engine_no=0 engine ver old_ver v0 v1 v2 v3 v4 + sort -u | while read -r dir; do + last_engine="$engine" + ruby="${dir##*/}"; engine="${ruby%%-*}"; ver="${ruby#*-}" + [[ "$last_engine" != "$engine" ]] && engine_no=$((engine_no + 1)) + v0="${ver%%\.*}"; ver="${ver#*\.}" + v1="${ver%%\.*}"; old_ver="$ver"; ver="${ver#*\.}" + [[ "$ver" == "$old_ver" ]] && ver="" + v2="${ver%%\.*}"; old_ver="$ver"; ver="${ver#*\.}" + [[ "$ver" == "$old_ver" ]] && ver="" + v3="${ver%%\.*}"; old_ver="$ver"; ver="${ver#*\.}" + [[ "$ver" == "$old_ver" ]] && ver="" + v4="${v2#*-p}" + [[ "$v2" == "$v4" ]] && v4="" + echo "$engine_no:$v0:$v1:$v2:$v3:$v4:$dir" + done | sort -nt: -k1 -k2 -k3 -k4 -k5 -k6 | cut -d: -f7- +} + +function chruby_detect_all_rubies() +{ + { + chruby_detect_rubies "$PREFIX/opt/rubies" + chruby_detect_rubies "$HOME/.rubies" + if [[ -n "$RUBIES" ]]; then + local chruby_rubies_dir + for chruby_rubies_dir in "${RUBIES[@]}"; do + chruby_detect_rubies "$chruby_rubies_dir" + done + fi + } | chruby_stable_version_sort +} + function chruby_reset() { @@ -71,7 +116,7 @@ function chruby() ;; "") local dir ruby - for dir in "${RUBIES[@]}"; do + chruby_detect_all_rubies | while read -r dir; do dir="${dir%%/}"; ruby="${dir##*/}" if [[ "$dir" == "$RUBY_ROOT" ]]; then echo " * ${ruby} ${RUBYOPT}" @@ -84,7 +129,7 @@ function chruby() system) chruby_reset ;; *) local dir ruby match - for dir in "${RUBIES[@]}"; do + chruby_detect_all_rubies | while read -r dir; do dir="${dir%%/}"; ruby="${dir##*/}" case "$ruby" in "$1") match="$dir" && break ;;