0

This question is the opposite of this one (also asked here, here and here)

I have two versions of ruby installed

ubuntu:~/environment $ rvm list

       ruby-2.6.6 [ x86_64 ]
    =* ruby-3.0.2 [ x86_64 ]

and every time I open a terminal window, ruby-3.0.2 (the default) is set. The problem is for a couple of my older projects I have to use ruby-2.6.6, so every time I have to switch with

rvm use 2.6.6

Is there a way to automatically select ruby 2.6.6 when I open the terminal window of the specific projects? I have tried to override the default rvm version with the .ruby-version file (as suggested here) but it does not do the trick.

EDIT File /home/ubuntu/.rvm/scripts/cd contains the following

#!/usr/bin/env bash

# Source a .rvmrc file in a directory after changing to it, if it exists.  To
# disable this feature, set rvm_project_rvmrc=0 in /etc/rvmrc or $HOME/.rvmrc
case "${rvm_project_rvmrc:-1}" in
1|cd)
  # cloned from git@github.com:mpapis/bash_zsh_support.git
  source "$rvm_scripts_path/extras/bash_zsh_support/chpwd/function.sh"

  # not using default loading to support older Zsh
  [[ -n "${ZSH_VERSION:-}" ]] &&
  __rvm_version_compare "$ZSH_VERSION" -gt  4.3.4 ||
  {
    function cd()    { __zsh_like_cd cd    "$@" ; }
    function popd()  { __zsh_like_cd popd  "$@" ; }
    function pushd() { __zsh_like_cd pushd "$@" ; }
  }

  __rvm_after_cd()
  {
    \typeset rvm_hook
    rvm_hook="after_cd"
    if [[ -n "${rvm_scripts_path:-}" || -n "${rvm_path:-}" ]]
    then source "${rvm_scripts_path:-$rvm_path/scripts}/hook"
    fi
  }
  __rvm_cd_functions_set()
  {
    __rvm_do_with_env_before
    if [[ -n "${rvm_current_rvmrc:-""}" && "$OLDPWD" == "$PWD" ]]
    then rvm_current_rvmrc=""
    fi
    __rvm_project_rvmrc >&2 || true
    __rvm_after_cd || true
    __rvm_do_with_env_after
    return 0
  }
  [[ " ${chpwd_functions[*]} " == *" __rvm_cd_functions_set "* ]] ||
  chpwd_functions=( "${chpwd_functions[@]}" __rvm_cd_functions_set )

  # This functionality is opt-in by setting rvm_cd_complete_flag=1 in ~/.rvmrc
  # Generic bash cd completion seems to work great for most, so this is only
  # for those that have some issues with that.
  if (( ${rvm_cd_complete_flag:-0} == 1 ))
  then
    # If $CDPATH is set, bash should tab-complete based on directories in those paths,
    # but with the cd function above, the built-in tab-complete ignores $CDPATH. This
    # function returns that functionality.
    _rvm_cd_complete ()
    {
      \typeset directory current matches item index sep
      sep="${IFS}"
      export IFS
      IFS=$'\n'
      COMPREPLY=()
      current="${COMP_WORDS[COMP_CWORD]}"
      if [[ -n "$CDPATH" && ${current:0:1} != "/" ]] ; then
        index=0
        # The change to IFS above means that the \command \tr below should replace ':'
        # with a newline rather than a space. A space would be ignored, breaking
        # TAB completion based on CDPATH again
        for directory in $(printf "%b" "$CDPATH" | \command \tr -s ':' '\n') ; do
          for item in $( compgen -d "$directory/$current" ) ; do
            COMPREPLY[index++]=${item#$directory/}
          done
        done
      else
        COMPREPLY=( $(compgen -d ${current}) )
      fi
      IFS="${sep}";
    }
    complete -o bashdefault -o default -o filenames -o dirnames -o nospace -F _rvm_cd_complete cd
  fi
  ;;
2|prompt)
  if
    [[ -n "${ZSH_VERSION:-}" ]]
  then
    precmd_functions+=(__rvm_do_with_env_before __rvm_project_rvmrc __rvm_do_with_env_after)
  else
    PROMPT_COMMAND="${PROMPT_COMMAND%% }"
    PROMPT_COMMAND="${PROMPT_COMMAND%%;}"
    PROMPT_COMMAND="${PROMPT_COMMAND:-}${PROMPT_COMMAND:+; }__rvm_do_with_env_before; __rvm_project_rvmrc; __rvm_do_with_env_after"
  fi
  ;;
esac
kouroubel
  • 260
  • 4
  • 18

1 Answers1

0

You are probably using RVM as a shell script, and not as a shell function.

You can check like this in a typical shell (bash, zsh, ...) : execute: type rvm

If it displays rvm is /home/ying/.rvm/bin/rvm : you are using as a script (found in $PATH)

If it displays rvm is a function : you are using as a function (much better).

Check out: https://rvm.io/rvm/basics#post-install-configuration

If you are using as a script, and want to use as a function: you need to "source" the rvm function, it is located in <rvm main folder>/scripts/rvm, for instance if installed in $HOME:

source $HOME/.rvm/scripts/rvm
source /usr/local/rvm/scripts/rvm

Typically, at RVM installation time, it add the following line in the equivalent of .profile (depending on shell and if its global or user):

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*

RVM changes automatically the version as described here:

https://rvm.io/workflow/projects

For detection of .ruby-version, the following is required:

  • RVM must be a recent version that supports the feature
  • RVM must be loaded in the shell (typically by .profile, or equivalent) so that is is executed as a function
  • the shell must be compatible with this callback feature (bash and zsh are)

Here is what happens:

  • When you load rvm as a function, it registers callback in the shell
  • when you cd into the project, RVM callbacks (in shell) detect the file .ruby-version (or others) and automatically do the equivalent of rvm use.

For instance, I use zsh (on osx) which has preexec and precmd callbacks and it detect the ruby version file and applies when I cd into it or a sub folder. It works with bash too.

If you are curious or want to see why it does not work for you look at the file <rvm main dir>/scripts/cd

typically the shell variable chpwd_functions is set to __rvm_cd_functions_set which is the function called after a cd by rvm

laurent
  • 111
  • 6
  • type rvm says I am using it as a function. See my original post for the contents of the cd file... – kouroubel Oct 21 '21 at 18:37
  • so, you open a new terminal. in this terminal you get a login shell on the system. (either by SSH, or because the terminal runs locally). then you change the current working directory to the project. in this directory is located the file: .ruby-version. if rvm is loaded as function and shell hooks are in place, it should find this file and change the ruby version. if it does not work, one of the steps above is wrong: – laurent Oct 21 '21 at 21:03
  • OK, it seems that when I open a terminal and then change the current working directory to the project, .ruby-version kicks in and version 2.6.6 is selected. What I was doing is open a terminal *directly* to the project. This does not work and the default version 3.0.2 is selected. This is a partial solution but very useful. Thank you... – kouroubel Oct 22 '21 at 05:38