Table of Contents
So, there was a time when I was only developing applications using
Python. And so I found out about virtual environments.
And then after a couple of months, I discovered
It also came to a time I had to work on multiple projects that uses different versions of
nodejs and searched something similar
so I installed
Then, I was required to work on a
Ruby project so I installed
golang was one of the new shiny objects that kinda got my interest, I went on and installed
Everything was fine until I kinda felt my
config.fish file got bloated and somehow
nvm was kinda slowing down my shell startup.
I did do some optimizations such as lazy loading
nvm and used a
fish plugin called fish-nvm.
And then one day, I found out about asdf-vm.
At first, I was quite hesitant to install it since it would kinda disrupt my work flow with python projects since I heavily use
pyenv virtualenv <version> <name>.
But I did feel that the benefits of using
asdf-vm outweighs the cons so I went ahead and proceeded.
$ git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.7.8
asdf has a pretty good documentation to be honest. Despite
brew being my go to package manager, I chose
git as my installation method.
My reason is that
asdf requires me to add this line in my
source (brew --prefix asdf)/asdf.fish
brew --prefix adsf is just too slow compared to just having this
Next, for the auto completions just run this command in your terminal:
$ mkdir -p ~/.config/fish/completions; and cp ~/.asdf/completions/asdf.fish ~/.config/fish/completions
Restart your shell so that PATH changes take effect!
You can checkout a more detailed documentation here: https://asdf-vm.com/#/core-manage-asdf-vm?id=install
config.fish looked something like this:
# pyenv set -gx PYENV_ROOT $HOME/.pyenv set -gx PYTHON_BUILD_ARIA2_OPTS "-x 10 -k 1M" # Use aria2c when downloading contains $PYENV_ROOT/bin $fish_user_paths; or set -Ua fish_user_paths $PYENV_ROOT/bin status --is-interactive; and pyenv init - | source status --is-interactive; and pyenv virtualenv-init - | source # goenv set -gx GOENV_GOPATH_PREFIX $HOME/.go status --is-interactive; and goenv init - | source # rbenv status --is-interactive; and rbenv init - | source # Set nvm aliases and add to path set -gx nvm_alias_output $HOME/.node_aliases contains $nvm_alias_output $fish_user_paths; or set -Ua fish_user_paths $nvm_alias_output
# pyenv (asdf still uses pyenv under the hood) set -gx PYTHON_BUILD_ARIA2_OPTS "-x 10 -k 1M" # Use aria2c when downloading # asdf source $HOME/.asdf/asdf.fish
Installing pyenv, rbenv, goenv, and nvm replacements #
Again, most of the things I put here just came from the documentation: https://asdf-vm.com/#/core-manage-plugins?id=add
pyenv replacement #
$ asdf plugin add python $ asdf install python latest:3 # At the moment of writing this, it installed 3.8.4 $ asdf global python 3.8.4 # This sets python 3.8.4 as our default python version
rbenv replacement #
$ asdf plugin add ruby $ asdf install ruby latest # We can omit the version number. Currently installs 2.7.1 $ asdf global ruby 2.7.1
goenv replacement #
$ asdf plugin add golang $ asdf install golang latest # 1.14.6 $ asdf global golang 1.14.6
nvm replacement #
$ asdf plugin add nodejs $ asdf install nodejs 12.18.2 $ asdf global nodejs 12.18.2
asdf global creates a file under your HOME directory called
$ cat ~/.tool-versions python 3.8.4 ruby 2.7.1 golang 1.14.6 nodejs 12.18.2
asdf know which versions to use. And of course, in contrast to
there is also the
local keyword that creates another
This is useful when projects require different version.
$ cd ~/project1 $ asdf local python 3.7.5 $ python --version # Uses the python version specified in .tool-versions 3.7.5 $ cd ~/project2 $ python --version # Uses the python version specified in ~/.tool-versions 3.8.4
asdf has a lot of plugins available. You can check them out here: https://github.com/asdf-vm/asdf-plugins
In order to accommodate my work flow when I was still using
I created a function that behaves quite similar to
$ touch ~/.config/fish/functions/venv.fish
And paste the following:
function venv --argument-names 'python_version' --description 'Create virtualenv named the same as current directory' set -l python_bin if not test -n "$python_version" # Use default python version set by asdf set python_bin ($HOME/.asdf/bin/asdf which python) else set python_bin $ASDF_DIR/installs/python/$python_version/bin/python end set -l venv_name (basename $PWD | tr . -) echo if not test -e $python_bin echo "Python version `$python_version` is not installed." return 1 end echo Creating virtualenv `$venv_name` $python_bin -m venv $HOME/.virtualenvs/$venv_name source $HOME/.virtualenvs/$venv_name/bin/activate.fish end
Whenever I’m inside a python project, I just need to type
and it will automatically create a virtualenv under
~/.virtualenvs using the current directory name.
In order to automatically activate the virtualenv when
cding to a project, do the following:
$ touch ~/.config/fish/conf.d/__auto_venv.fish
And paste the following:
function __auto_venv --on-variable PWD --description "Automatically activate python venv" set -l venv_name (basename $PWD | tr . -) if test -d $HOME/.virtualenvs/$venv_name source $HOME/.virtualenvs/$venv_name/bin/activate.fish end end
Cool! Not only did I reduce the lines in my
config.fish, I could also notice a decreased startup time which is a good thing!
You can also check out my dotfiles in my GitHub repository: https://github.com/yujinyuz/dotfiles
I hope this article helped you! You can leave a comment below and I’ll try to answer them as fast as I can.
Thanks for reading! 🎉