Managing Elixir runtime version with asdf
23/Dec 2017
An uncomfortably common problem when developing for a particular programming
language is needing to deal with compatibility issues across different
versions of the language runtime. Most often this means keeping individual
projects tied to their then-current version of the language until such time
that the project can address any compatibility issues with later language
releases. To that end, Ruby developers are probably familiar with
one of rbenv, chruby or rvm, for example. Elixir isn’t much different
in this regard.
One available project that I find pretty promising is asdf, which is
self-described as:
[An] extendable version manager with support for Ruby, Node.js, Elixir, Erlang & more
It fulfills some of the same roles that rbenv and friends do, while
supporting multiple languages and even other software tools in a fairly
standardized way.
Installation
Homebrew
brew install asdfFollow the instructions in the output, which you can read again with brew
info asdf if you missed them. As of this writing, those instructions are:
Add the following line to your bash profile (e.g. ~/.bashrc, ~/.profile, or ~/.bash_profile)
source /usr/local/opt/asdf/asdf.shIf you use Fish shell, add the following line to your fish config (e.g. ~/.config/fish/config.fish)
source /usr/local/opt/asdf/asdf.fish
Git
You can follow the latest manual installation instructions from the project’s README, but today it includes:
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.4.0
# install shell hooks
# I personally prefer `source` to `.`
# bash users
echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bash_profile
echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bash_profile
# zsh users
echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.zshrc
echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.zshrc
# fish users
echo 'source ~/.asdf/asdf.fish' >> ~/.config/fish/config.fish
mkdir -p ~/.config/fish/completions; and cp ~/.asdf/completions/asdf.fish ~/.config/fish/completionsPrerequisites
At the time of writing, here are the prerequisites recommended to use
asdf, which can be installed with Homebrew:
brew install autoconf automake coreutils \
libtool libxslt libyaml openssl \
readline unixodbcInstall required asdf plugins
You can check the available plugins, based on the open-source plugin index here:
asdf plugin-list-allAfter identifying desirable plugins:
asdf plugin-install erlang
asdf plugin-install elixir
# phoenix users will likely also want:
asdf plugin-install nodejsUsage
To install the latest Erlang and Elixir versions at the time of writing:
asdf install erlang 20.2
asdf install elixir 1.5.3Phoenix users will also want:
asdf list-all nodejs
asdf install nodejs 9.3.0Checking available tool versions
You can see what versions asdf currently supports for installation with
this command:
# asdf list-all [plugin]
asdf list-all erlang
asdf list-all elixir
asdf list-all nodejsEach plugin is able to implement this behavior in its own way, so their
behavior may vary. Some are able to directly examine the releases of the
upstream language project, others require manual support within the asdf
plugin in question, and so may lag behind new releases.
Installing a specific Erlang patch version
The author of asdf, @HashNuke on GitHub, cleared up in this GitHub issue
that any tagged release of Erlang can be installed with asdf-erlang:
We already support it. You can do the following:
asdf install erlang ref:OTP-20.1.2Where OTP-20.1.2 is a valid tag that you can find on https://github.com/erlang/otp/releases. You can also specify a commit sha or branch name if you insist on the latest super-powers.
As of this writing the latest release is 20.2.2, so that can be installed like so:
asdf install erlang ref:OTP-20.2.2
# set global default
asdf global erlang ref:OTP-20.2.2Installing Elixir from master
If you’d like to use the latest and greatest features, such as the
upcoming
mix
format command slated for inclusion in Elixir 1.6, you can install the
current version of the elixir-lang/elixir repository’s master branch:
asdf install elixir masterYou can use this version all the time via asdf global or asdf local,
or on one-off commands by setting the ASDF_ELIXIR_VERSION environment
variable to master.
Per-project tool versions
By using asdf local, you can configure pre-project tool versions, which
are persisted in a project-local .tool-versions file you may wish to
include in your global .gitignore. When revisiting a project later, you
can run asdf install with no additional arguments to ensure that the
project’s desired software versions are available.
Keeping up to date
To update asdf itself:
asdf updateTo update asdf plugins:
# update all plugins
asdf plugin-update --all
# update individual plugin
asdf plugin-update erlangTroubleshooting
You can inspect where a particular version of a particular language is
installed with asdf where:
asdf where erlang 20.2
# /Users/shane/.asdf/installs/erlang/20.2You can make sure that newly-installed binaries (such as those installed by
npm) are detected by using asdf reshim:
asdf reshim nodejs 9.3.0
# no outputYou can inspect which specific binary will be used in your current context,
accounting for both global and local tool versions, with asdf which:
asdf which erlang
# /Users/shane/.asdf/installs/erlang/20.1/bin/erlangOther notable plugins
Here are a few other asdf plugins I’m prone to using in the course of my infrastructure-focused work:
Alternatives
There are many alternative options for installing Elixir. Here are a few in no particular order and with no specific endorsement:
- Homebrew (
brew install erlang elixir node) - Nix package manager and
nix-shell(blog post forthcoming!) - kiex and kerl
Software/Tool Versions
| Software | Version |
|---|---|
| OSX | 10.12.6 |
| asdf | 0.4.0 |
| Elixir | 1.5.3 |
| Erlang | 20.2.2 |
| Node.js | 9.3.0 |