Skip to content

Instantly share code, notes, and snippets.

@jwarner112
Last active September 16, 2021 04:56
Show Gist options
  • Save jwarner112/b0690921b1a56fe104a3c03de1d7b312 to your computer and use it in GitHub Desktop.
Save jwarner112/b0690921b1a56fe104a3c03de1d7b312 to your computer and use it in GitHub Desktop.
Introduction to the ASDF Version Manager

The ASDF version manager: an introduction

Introduction

Have you ever had to manage more than one version of a tool at once? If you're a developer, you probably have. Some tools have this in mind with solutions to make it easier -- Python has virtual environments, as one example. For those that don't (and some that do), third-party tooling arises to fill the gap.

Some examples:

Tool Version Managers other than ASDF
Python pyenv, or pip sorta
Ruby rbenv, rvm, chruby, ...
NodeJS n, nvm, fnm, ...
Elixir exenv, kiex, ...
Golang g, gvm, goenv, ...
Redis None?
Postgres None.
protoc None!
yq Dream on!

As you may notice, version management is more or less a thing develoers have to deal with on a local computer and the solution space reflects that -- languages have many. But Redis and Postgres have none, even if version juggling needs to be done sometimes. And yq, a command-line YAML parser, has no such manager even though its interface is completely different starting in v4. This is where ASDF shines.

Installation

To get it set up, just follow the installation guide -- it's very good!

After installation of the tool and a plugin, use its CLI to install a version of a tool. It will live entirely within ASDF’s folder, which is by default $HOME/.asdf.

Common Usage

To see the list of available plugins, use asdf plugin list all; this index (and the indexes of the plugins’ managed versions) are all managed via Git. So, on an existing install you may want to run asdf update to get the latest set of fixes/plugins. To update your plugins’ indexes you can run asdf plugin update <tool> or asdf plugin update --all.

For ruby, after ASDF has been installed/loaded, you would do

$ asdf plugin add ruby
$ asdf list ruby           # will show up blank, since you have none installed
$ asdf list all ruby       # will show all versions that you can install
$ asdf install ruby 2.7.4  # will take awhile as it downloads/compiles dependencies like OpenSSL from scratch

Installation is mostly painless but it depends on how each plugin (user-contributed) is built. In my experience Python, Node, and Ruby plugins all work the same and work well.

Once installed, there’s a few ways to load that version onto your session

$ asdf shell ruby 2.7.4   # sets the version for JUST THIS SESSION (uses an ASDF_*_VERSION variable)
$ asdf local ruby 2.7.4   # creates/appends to a `.tool-versions` file in the current directory that gets auto-loaded and unloaded as you enter/leave this directory or a subdirectory
$ asdf global ruby 2.7.4  # creates a `.tool-versions` in `$HOME`, effectively setting this version for the whole user

Use as desired. A .tool-versions in your project + added to your global .gitignore is a common flow I’ve seen and use myself.

To see exactly which version of a thing you’re running, use asdf current <tool>; also shows how the thing was set

$ asdf current ruby
ruby            2.7.4           ASDF_RUBY_VERSION environment variable

To see which versions of everything ASDF is managing, omit the <tool>:

$ asdf current
elixir          ______          No version set. Run "asdf <global|shell|local> elixir <version>"
golang          ______          No version set. Run "asdf <global|shell|local> golang <version>"
helm            ______          No version set. Run "asdf <global|shell|local> helm <version>"
nodejs          ______          No version set. Run "asdf <global|shell|local> nodejs <version>"
postgres        13.3            ASDF_POSTGRES_VERSION environment variable
protoc          ______          No version set. Run "asdf <global|shell|local> protoc <version>"
python          3.9.6           /Users/jeff/.tool-versions
redis           ______          No version set. Run "asdf <global|shell|local> redis <version>"
ruby            2.7.4           ASDF_RUBY_VERSION environment variable
rust            ______          No version set. Run "asdf <global|shell|local> rust <version>"

To see the exact path where your tool/language/runtime has been installed, use asdf where:

/Users/jeff/.asdf/installs/ruby/2.7.4

ASDF operates using shims, tiny dynamically generated bash scripts that route commands to the proper versions. So any command you issue to a tool is usually routed through ~/.asdf/shims. If for some reason you’re facing weird problems, asdf reshim will regenerate the current environment’s set of shims and may fix your issue.

To see exactly which binaries the commands are being routed to, use asdf which:

/Users/jeff/.asdf/installs/ruby/2.7.4/bin/ruby

The same applies for any bin that the package usually comes with:

/Users/jeff/.asdf/installs/ruby/2.7.4/bin/gem
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment