How does RVM detect when you've changed direct

2019-02-01 20:18发布

问题:

One thing that RVM can do is notice when you've changed directories, look for an .rvmrc, and change your current Ruby version and gemset according to that file's contents. It makes this change as soon as you change into that directory and outputs a message accordingly.

How does it detect a change in the current working directory? I can imagine an extremely crude way of doing this: run a daemon that runs as the current user and keeps checking the results of pwd. But I'm sure that's not what it does.

Another approach might be to alias cd to change directories but also check for an .rvmrc and change gemsets if so instructed.

Is there a Unix system hook for changing directories, or is there some other trick that RVM is using?

回答1:

How does [RVM] detect a change in the current working directory?

This entirely depends on the shell and even shell version. The simplest method for accomplishing this is, as was suggested, overriding cd by defining a function of the same name. Be sure to call the built in cd function or you will cause either very nasty or very amusing side effects (depending on perspective).

cd() {
  builtin cd $*
  echo "Changed directories from '${OLDPWD}' to '${PWD}'."
}

By placing this in a text source file and sourcing the file you can load this custom cd functionality into the session sourcing the file.

wayneeseguin$ cd /tmp
Changed directories from '/home/wayneeseguin' to '/tmp'.

If you would like this to always be in effect for interactive shells in your user account either place the function definition into ~/.bash_profile. Alternatively you can source the text file in which you stored the function in from ~/.bash_profile. You can read more about Bash startup files in the Bash manual.

The Ruby enVironment Manager (RVM) is written in and targeted mainly for the Bash shell. RVM will work in the ZSH shell which allows you to add function calls to after a cd action. This is by far the best way to approach solving this task. So, if your shell allows for it, by all means use this method. RVM does.

For an extensive example you can look at RVM's cd functionality on GitHub.

RVM utilizes this functionality for loading per-project (directory, really) .rvmrc files as well as providing users with the ability to configure various hooks. You can read more about RVM's hooks on the documentation website.



回答2:

When you install rvm you have to add:

[[ -s $HOME/.rvm/scripts/rvm ]] && source $HOME/.rvm/scripts/rvm

to your shell config (usually .bashrc or .zshrc).

This loads RVM when you start a shell which then overrides your cd command and checks for .rvmrcs as you move around. See the contents of $HOME/.rvm/scripts/cd for more details.



回答3:

Does it just look at the current directory whenever it needs to resolve the contents of the gemset? Is there something that makes you think it's doing this in parallel with changing directories, rather than on demand?



标签: rvm internals