Stratus3D

A blog on software engineering by Trevor Brown

Asdf Tip: Global Programs

Every so often I install a program via gem, npm or some other language specific package manager and want it to be available globally on my system. Npm has the -g flag but this doesn’t help when I change Node versions. The same goes for Ruby. If I switch to a different version of Ruby I can’t use the command I installed in the earlier version.

A concrete example of this is the excellent Tmuxinator gem. The gem allows tmux sessions to be defined in yaml files. When a project is opened with the tmuxinator command it creates the session defined in the yaml file for the project automatically. Since Tmuxinator is a gem it’s only available under the version of Ruby it was installed in. If I change to a directory that’s set to use a different version of Ruby my tmuxinator command won’t be available. I really don’t want to have to install the same gem in every version of Ruby I use. It would be wasteful to have multiple installations of the same gem and upgrading all those installations would be a hassle.

Thankfully there is an easy way to handle this if you are using asdf. asdf reads environment variables that are in the format ASDF_<LANGUAGE>_VERSION. In our case this is a Ruby gem, so we need to set ASDF_RUBY_VERSION to the right version of Ruby before executing tmuxinator. To do this you can create a simple alias or shell script. Either will work and both have their advantages. Aliases are shorter and easier to create. Assuming you’ve installed Tmuxinator under Ruby 2.3.0 the alias should look like this:

alias tmuxinator="ASDF_RUBY_VERSION=2.3.0 tmuxinator"

Just add that line to your .bashrc or .zshrc and you should have have a tmuxinator alias that works in any directory, even directories that are set to use different versions of Ruby. You can name the alias anything you want. A different name may be useful if you want to differentiate this global tmuxinator alias from another instance of tmuxinator installed on your system.

A slightly more involved solution is to use a shell script. Even this isn’t that hard to do. All you need to do is create a file with the name you want the command to have (just like the name of the alias above). The file should be placed in a directory on you $PATH (I have $HOME/bin/ for scripts like this). Then run chmod +x <filename> to set the execution permission for the file. Finally open it up in your editor and enter in the following:

#!/usr/bin/env bash

export ASDF_RUBY_VERSION=2.3.0
exec tmuxinator

That’s it! This will work just like the alias, and if it’s on your $PATH it will be available from every directory. The exec line tells Bash to execute the actual tmuxinator program in the same process as the script, rather than spawning another process as it normally would. This makes it slightly more efficient than just calling tmuxinator directly.

References

  • Tmuxinator: https://github.com/tmuxinator/tmuxinator
  • asdf: https://github.com/asdf-vm/asdf
  • Issue discussed on the rbenv issue tracker: https://github.com/rbenv/rbenv/issues/276