If you develop on different projects in different languages it can happen that different versions of the respective scriptin languges are used. To use different versions of your development language nevertheless keep your system clean is the purpose of environment managers. In the following article I want to talk about such environment managers, which I use for my daily work.
My first contact with an environemnt manager was within a python project. So I will start with python here follow by ruby and node.js.
Python
Note: As I never use python2 for development I also have no need to use other versions as 3.x for my development. So this article also only covers python3 virtual environments.
venv
The simpliest way to install an virtual enviroment with python is to use the venv
module.
nero@matrix:~/Development/venv$ python3 -m venv venv
nero@matrix:~/Development/venv$ source my_venv/bin/activate
(venv) nero@matrix:~/Development/venv$ python --version
Python 3.8.5
pyenv
Warning: To use venv
is a very simple method but it is also the most limited. You are not able to install different python versions with this module.
Therefore I looked around for a better solution and found pyenv. With this manager it is possible to install many different versions of python on your system and create virtual environments from there.
installing pyenv
To use pyenv
you can either do all steps by hand as described on the project page but I suggest pyenv-installer instead. It installs pyenv
with a simple curl call.
curl https://pyenv.run | bash
The script clones the pyenv and some plugin repositories. Your have to add the following lines to your .bash_profile
or .bashrc
file:
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
installing python and using versions of choice
After these small steps the environment manager is ready for each new shell session and you can begint to install python versions of your choice.
pyenv install <VERSION>
Now you can create a virtual environment with it and start working isolated.
pyenv virtualenv <VERSION> <VENV>
pyenv activate <VENV>
From now on you work on the selected version and all pip’s are installed in your virtualenv.
activating pyenv environment automatically
If you place a file named .python-version
in a directory with the virtualenv inside it will we activated if you enter the directory.
If you leave the direcotry the virtualenv will be deactivated.
Ruby
With the experiences I collected while programming with python in virtual environments I also started my ruby journey also with an environment manager.
One of my colleagues recommended rvm which seems to be the defacto standard for managing ruby environments.
installating rvm
To install it you simply have to run the follwing two commands:
gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
curl -sSL https://get.rvm.io | bash -s stable --auto-dotfiles
installing ruby and using versions of choice
Now you’re able to install and use diffrent ruby versions on your system. First install a ruby version.
nero@matrix:~$ rvm install 2.7.1
After that create a gemset for the given version to separate gems for your environment from your system ruby.
rvm use <VERSION>
rvm gemset create <GEMSET>
activating rvm environment automatically
To automatically activate a version and gemset you have to place a .ruby-version
and a .ruby-gemset
file in your directory. If you enter the directory ruby version and/or gemset will be activated. If you leave the directory it will be also deactivated.
node.js
Finally I started a few month ago to work with node.js and I wanted to start with an environment manager too. I found nvm as the best candidate as my manager of choice.
installing nvm
A simple command will install all needed commands to your system and put necessary settings to your shell profile file to load the enviroment manager correctly.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
installing node and using versions of choice
To use nvm
for instaling different versions of node you have to do the following:
nvm install <VERSION>
nvm use <VERSION>
activating nvm environment automatically
To activate npm version like in pyenv
or rvm
if you enter a directory you need an extra configuration. I prefer to put the following code in a file like ~/.nvm/autoload.sh
and source it in .bashrc
.
find-up() {
path=$(pwd)
while [[ "$path" != "" && ! -e "$path/$1" ]]; do
path=${path%/*}
done
echo "$path"
}
cdnvm() {
cd "$@";
nvm_path=$(find-up .nvmrc | tr -d '\n')
# If there are no .nvmrc file, use the default nvm version
if [[ ! $nvm_path = *[^[:space:]]* ]]; then
declare default_version;
default_version=$(nvm version default);
# If there is no default version, set it to `node`
# This will use the latest version on your machine
if [[ $default_version == "N/A" ]]; then
nvm alias default node;
default_version=$(nvm version default);
fi
# If the current version is not the default version, set it to use the default version
if [[ $(nvm current) != "$default_version" ]]; then
nvm use default;
fi
elif [[ -s $nvm_path/.nvmrc && -r $nvm_path/.nvmrc ]]; then
declare nvm_version
nvm_version=$(<"$nvm_path"/.nvmrc)
declare locally_resolved_nvm_version
# `nvm ls` will check all locally-available versions
# If there are multiple matching versions, take the latest one
# Remove the `->` and `*` characters and spaces
# `locally_resolved_nvm_version` will be `N/A` if no local versions are found
locally_resolved_nvm_version=$(nvm ls --no-colors "$nvm_version" | tail -1 | tr -d '\->*' | tr -d '[:space:]')
# If it is not already installed, install it
# `nvm install` will implicitly use the newly-installed version
if [[ "$locally_resolved_nvm_version" == "N/A" ]]; then
nvm install "$nvm_version";
elif [[ $(nvm current) != "$locally_resolved_nvm_version" ]]; then
nvm use "$nvm_version";
fi
fi
}
alias cd='cdnvm'
cd $PWD
Now nvm
behaves same like the other both tools. You simply need to place a .nvmrc
file with a installed version string inside in a directory of your choice.