I’ve been using erln8 for years. My buddy Dave wrote it because wanted a way of switching Erlang versions automatically when entering a directory. It’s done that job well for me for years, but it seems to be showing its age. There’s a v2 that never quite got --with-ssl working, so I couldn’t rely on that.

Kerl, on the other hand, seems to get a lot more love from the maintainers. Since Mark is a stand up fellow, I thought I would see if I could get the one feature I need from erln8 working with kerl.

SPOILER ALERT: I can!

Installation

$ brew install kerl

I was using curl to install kerl, but Michael Coles dropped the hot tip that a homebrew’d kerl will install the completions for you for free!

Nathan Smith let me know that as of kerl v1.3.3, kerl will detect your homebrew version of openssl all by itself!

We’re going to need one more tool to get that killer feature of erln8 that kerl is missing: direnv

$ brew install direnv

Configuration

We’ll have to tell kerl that we want git releases, because gitbub/erlang/otp gets tagged way more than erlang.org gets releases, so let’s just set up a ~/.kerlrc file now:

## These are defaults but I want it explicitly set
export KERL_BASE_DIR=$HOME/.kerl
export KERL_DEFAULT_INSTALL_DIR=$KERL_BASE_DIR/installs
## Build from github
export KERL_BUILD_BACKEND=git
## This is how I like my builds, but doowutchyalike
export KERL_CONFIGURE_OPTIONS="--with-wx --enable-smp-support --enable-threads --enable-kernel-poll --enable-darwin-64bit"

Let’s make sure those variables wind up in the ENV for everyone, we’ll need them in scope for direnv and emacs

I like this kind of stuff in my ~/.profile, but ~/.zshrc will also work.

if [ -f ~/.kerlrc ]; then
    source ~/.kerlrc
fi

At this point it probably makes sense to build at least two versions, so we can make sure everything switches up the way we want

$ kerl build 19.1.2 19.1.2
... coffee ...
$ kerl install 19.1.2
$ kerl build 18.3.4.4 18.3.4.4
... moar coffee ...
$ kerl install 18.3.4.4

Hope you didn’t take that advice about the coffee too seriously. Erlang builds aren’t the fastest, but hey maybe you made a cold brew… you probably had the time.

While you’re doing that, you can start getting direnv ready to go. I’m in zsh, probably works the same in bash, something weird probably happens with fish, which is why I stopped using it. Amazing shell, until you need POSIX.

The command you need to insert direnv into your ~/.zshrc

$ echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc

We’ll want to add this cool helper function for kerl to direnv so let’s do that now:

~/.config/direnv/direnvrc

use_kerl () {
    . $KERL_DEFAULT_INSTALL_DIR/$1/activate
}

So, now we have direnv installed and working. We’ve got two versions of erlang installed via kerl. We’ve also set up a helper function in direnvrc, so now we’re pretty much in business.

now you can go into a project and create a .envrc file that looks like this:

use kerl 19.1.2

AND THAT’S IT This dir will use 19.1.2 until you change this .envrc

Let’s make sure you have a default ERLANG ready to go when you’re anywhere else:

In your ~/.profile, below the part where you source ~/.kerl

export ERLANG_VERSION="19.1.2"
. $KERL_DEFAULT_INSTALL_DIR/$ERLANG_VERSION/activate

Why are we exporting ERLANG_VERSION anyway? Well, stay tunned for an emacs & erlang post.