Programming Language Management
nix
aside1, I recently shifted to using asdf to manage different language versions.
1git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.8.1
The main reason to prefer asdf
over competing language specific options like rvm
or pyenv
or nvm
and company is simply uniformity of the interface. This can be coupled with zinit snippet OMZ::plugins/asdf
for loading the completions. Note that the installation steps can take a while especially if openssl
is being installed.
Configuration
Actually one weird aspect of asdf
is that it pollutes $HOME
by default
instead of respectfully storing its configuration in $HOME/.config/asdf
like
every other program. To change this; exporting ASDF_CONFIG_FILE
works.
Essentially a zsh
configuration with zinit
would look like this2:
1if [[ ! -d ~/.asdf ]]; then
2 mkdir ~/.asdf
3 git clone https://github.com/asdf-vm/asdf.git ~/.asdf
4fi
5
6export ASDF_CONFIG_FILE="~/.config/asdf/asdfrc"
7zinit snippet OMZ::plugins/asdf
asdf
has an option; legacy_version_file = yes
which is meant to ensure that
existing solutions (e.g. .nvmrc
or .node-version
) are compatible. There is
also $HOME/.tool-versions
for trickle-down language versions; that is
language-version pairs defined in such files are activated for the directory and
lower sub-directories. The rest of a reasonable configuration (described here)
might look like:
1legacy_version_file = yes
2always_keep_download = no
Ruby
This plugin leverages ruby-build and so can take a pick up an extended set of
environment variables; it supports .ruby-version
files as well.
1asdf plugin add ruby
2asdf list all ruby
3asdf install ruby 3.0.2
4asdf global ruby 3.0.2 # Convenience
NodeJS
This plugin respects .nvmrc
and .node-version
files.
1asdf plugin add nodejs
2asdf global nodejs latest
3asdf install nodejs latest
Python
Builds with python-build.
1asdf plugin add python
2asdf install python 3.9.7
3asdf global python 3.9.7
Direnv
I’m a huge fan of direnv
; and a fantastic little plugin (with neat hyperfine
benchmarks) for asdf
removes a layer of shim indirection while playing nicely with direnv
.
1asdf plugin-add direnv
2asdf install direnv latest
3asdf global direnv latest
This comes with an associated set of shell profile instructions:
1# File: ~/.zshrc
2# Hook direnv into your shell.
3eval "$(asdf exec direnv hook zsh)"
4# A shortcut for asdf managed direnv.
5direnv() { asdf exec direnv "$@"; }
Along with a commiserate $HOME/.config/direnv/direnvrc
requirement:
1source "$(asdf direnv hook asdf)"
Now every new .envrc
can start with use asdf
which will now speed up evaluations.
Conclusions
This method appears to be more robust than remembering the various idiosyncrasies and logic of a host of other tools.
This was during the build plan dynamism RFCs which themselves were symptomatic of the
{yarn,composer,node,*}2nix
issues ↩︎This structure can be seen in my own Dotfiles as well ↩︎