ASDF: Automatic Management of Multiple Versions
Ludal 🚀
Posted on April 18, 2022
Have you ever been in this situation where you are working on multiple projects and have to deal with multiple versions of Java, NodeJS or Postgres? In this article, we’ll discover how to switch between different runtime versions automatically depending on the current folder, and therefore the project. 📁
Setting the Scene
As a freelance developer working on different projects for different clients, you have probably already found yourself in this situation: project A runs with Java 8, project B runs with Java 11, and project C runs with Java 17. To easily switch between these versions, you might have used the update-alternatives
command.
sudo update-alternatives --config java
This works pretty fine, but there is a drawback to this approach: you have to manually run this command every time you have to switch to another version, which can quickly get cumbersome. Also, this command does not work with all tools, such as node
or postgres
.
One way to solve this problem is to use Docker. Indeed, the purpose of Docker is to create an image that contains all the correct versions for the current project. However, not everyone knows Docker, and not every project has a Dockerfile to build this setup. Also, not all teams have the time to build a Dockerfile: depending on the project size, it can easily get complicated to create one quickly.
Another solution would be to have something like a magic wand that automatically switches between Java 8 in the project-A
folder and Java 11 in the project-B
folder, and so on.
Actually, this magic wand exists, and is called asdf. 🪄
ASDF: Our Magic Wand
So what really is asdf
? It is a CLI tool that automatically switches between your runtime versions (Java, NPM, Node, Postgres, PHP, and even more) depending on your current folder. To do so, it relies on a file named .tool-versions
(located in the folders where you need to use it) to know which version to use for each tool. This file simply contains a mapping list of each tool with the correct version to use.
java openjdk-17
nodejs 17.3.0
postgres 13.5
When your current folder does not contain a .tool-versions
, asdf
will just look in the parent folders to find the first one containing such a file. As a result, you need to define a default version for each tool, so that asdf
can use this default version if no .tool-versions
file was found in the parent folders. The default versions are stored in your home directory: ~/.tool-versions
.
Something really interesting is that you can commit this .tool-versions
file to your git repository so that your colleagues can also have the correct versions of the different tools, as long as they are using asdf
. 💪🏼
An Example
Let’s say your default node
version is 17.3.0, but one of the projects you are working on is a bit old and uses version 12.13.0. If you start a terminal and run the command to get the node
version, it will display your current one.
$ node --version
v17.3.0
This command will produce the same output if you are in the project-A
folder. However, if you tell asdf
that it should use the version 12.13.0 of node
in this project, the output will change.
$ asdf local nodejs 12.13.0
$ node --version
v12.13.0
And if you change to another directory, the node
version will magically change back to your default one.
$ cd ..
$ node --version
v17.3.0
Totally crazy, right? 🤯 Let’s now see how to set-up asdf
(spoiler alert: it is ridiculously easy).
Setting Up ASDF
In the first place, you will need to download asdf
(available on Linux and MacOS, but unfortunately
not on Windows). To do so, just clone the git repository to your home folder.
git clone https://github.com/asdf-vm/asdf.git ~/.asdf
If you are on MacOS, you can simply use
brew
.brew install asdf
Once done, you will need to add these two lines to your .bashrc
(or .zshrc
).
. $HOME/.asdf/asdf.sh
. $HOME/.asdf/completions/asdf.bash
And that’s it, you’ve successfully installed asdf
! 🎉
Usage
To use asdf
, you will first need to add the plugins you need. A plugin corresponds to a tool: for instance, you will need to add the java
plugin to switch between java versions, the nodejs
plugin to switch between NodeJS versions, and so on. To add a plugin, simply run the following command:
asdf plugin add [plugin]
In this example, we will continue with nodejs
, so we will install this plugin.
asdf plugin add nodejs
💡 You can list all the available plugins with the
asdf plugin list all
command. As this will produce a pretty big list, you can filter the results withgrep
.asdf plugin list all | grep node
Now that we’ve added the nodejs
plugin, we will need to download the versions we want to use. In our case, we want both 12.13.0 and 17.3.0 versions.
asdf install nodejs 12.13.0
asdf install nodejs 17.3.0
After installing these versions, the last step is to specify which one to use depending on the project. To do so, head over to the folder of the project that uses 12.13.0 (let’s say project-A
) and select the correct nodejs
version.
asdf local nodejs 12.13.0
And that’s it! The 12.13.0 version of Node will be used in the project-A
directory and sub-directories. 🥳
If you now run ls -al
in the project folder to list all the files, you will notice the .tool-versions
file that contains the correct Node version. You can commit it to your version control system.
nodejs 12.13.0
💡 When cloning the project containing this file, your colleagues don’t even have to manually install the listed versions: they can simply run
asdf install
, and the magic wand will take care of downloading all required versions.
Lastly, as we’ve seen earlier, we need to define a default version to use when we are in another folder which has no .tool-versions
file in it or in its parent folders. In our case, we want the default version of Node to be 17.3.0.
asdf global nodejs 17.3.0
💡 You can also specify a version for the current shell.
asdf shell nodejs 17.3.0
And that’s it, we’ve successfully got rid of the pain of having to manually switch between our runtime versions, thanks to our new magic wand. 🪄
Wrapping Up
Thanks to asdf
, our runtime versions are now managed automatically. When you need to use a new plugin, the steps will always be the same:
- Install the corresponding plugin:
asdf plugin add [plugin]
- Install all the versions you need:
asdf install [plugin] [version]
- Select the local version for each concerned project:
asdf local [plugin] [version]
- Select the default version for this plugin:
asdf global [plugin] [version]
For more information, or if you need help on this awesome tool, don’t hesitate to head over to asdf-vm.com. Also, feel free to star the GitHub Repository of asdf
to support the team behind this project. 😉
I hope this article was useful to you, and I’ll see you in the next ones. 🤘🏼
More Articles From Me
Posted on April 18, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.