Troubleshooting Ruby Gems
I had a some issues recently with running certain Ruby applications on my system. I'd get weird error messages on startup, or the application couldn't be found at all. I thought I'd put together a few notes on troubleshooting my installation, what the problem was, and how I tracked the issue down.
The problem
I have a couple of Ruby applications I run locally: nexmo-developer
and nexmo-oas-renderer
which are both packaged as Ruby Gems. I'd been getting a number of weird errors on startup. I'd run bundle
and still get issues. In certain circumstances the application could not be found at all. I finally had enough as it was causing a lot of pain trying to keep my Ruby applications running reliably, so I sat down to figure out what was going on. The issue turned out to be due to the interplay between the following:
rbenv
gem
bundle
I'll go through each of these very briefly and explain what they do in very simple terms.
rbenv
rbenv
allows you to install and manage multiple versions of Ruby. On a typical Mac setup you have a system Ruby, but most people (including me) leave this well alone and install rbenv
so you can easily install and switch between Ruby versions as required. rbenv
uses ruby-build
to do this. I installed rbenv
using brew
. There are a few useful commands to use with rbenv
:
Command | Description |
---|---|
rbenv versions |
Displays all the installed versions you might have on your system, including the currently selected version (shown by a * ). |
rbenv install |
Allows you to install a specific version of Ruby, for example, rbenv install 2.5.8 |
rbenv global |
Allows you to set a version of Ruby to be used globally, for example, rbenv global 2.5.8 |
gem
The gem
command allows you to install a Ruby application packaged as a Gem. For example, to install the neocities
command line tool you'd type gem install neocities
. You can think of this as a "global install". You can see where the Gem has been install to by using gem info <package>
, for example:
$ gem info neocities
*** LOCAL GEMS ***
neocities (0.0.15)
Author: Kyle Drake
Homepage: https://neocities.org
License: MIT
Installed at: /Users/tbedford/.rbenv/versions/2.5.8/lib/ruby/gems/2.5.0
Neocities.org CLI and API client
You'll notice the Gem is installed in a version-specific location, in this case 2.5.8 (I was running 2.5.8 when I installed this Gem). If for example I switch to Ruby 2.5.7 with rbenv global 2.5.7
and tried to run neocities
I'd get the following:
rbenv: neocities: command not found
The `neocities' command exists in these Ruby versions:
2.5.8
This is important!
If I switch back to 2.5.8 with rbenv global 2.5.8
and run the command again I get:
neocities
|\---/|
| o_O | Neocities
\_o_/
Subcommands:
push Recursively upload a local directory to your site
upload Upload individual files to your Neocities site
delete Delete files from your Neocities site
list List files from your Neocities site
info Information and stats for your site
logout Remove the site api key from the config
version Unceremoniously display version and self destruct
pizza Order a free pizza
Note you can use the command line to order a free pizza! ;)
By the way, to figure out what version of gem
you are running you can enter gem -v
. To update the gem
command itself (but not the installed packages/gems) use the following:
gem update --system
bundle
OK so there's this thing called bundler
. It's a dependency manager for Ruby applications. What is does is it processes a Gemfile
in your applications directory, and from that figures out dependencies and makes sure they are installed too. For example, looking at the Gemfile for our api-specification
repo we have:
source 'https://rubygems.org'
gem 'nexmo-oas-renderer', '~> 2.1'
This means we require the nexmo-oas-renderer
to render specs locally, and the version required is identical to >= 2.1 and < 3.0. So, if you decide you want to install this Gem and its dependencies (of which there are many), you'd enter bundle
and the dependencies would be determined and installed along with the main app. Of course these will be installed in a location dependent on the version of Ruby you're currently running. In my case:
$ gem info nexmo-oas-renderer
*** LOCAL GEMS ***
nexmo-oas-renderer (2.1.3)
Author: Fabian Rodriguez
Homepage: https://github.com/Nexmo/nexmo-oas-renderer
License: MIT
Installed at: /Users/tbedford/.rbenv/versions/2.5.8/lib/ruby/gems/2.5.0
OpenAPI Specification renderer.
My issue
With multiple versions of Ruby and a various Gems installed for different versions of Ruby using different methods over the last year or so, it was only a matter of time before I ran into problems. For example, gems installed using version 2.5.7 would not longer be available after I switched to 2.5.8. I also installed gems using different methods. For example, some time past I downloaded both Nexmo renderer and Station source repositories and installed them from the source. These would then potentially conflict with versions installed via bundler
. To get around this I used gem uninstall
to remove all versions. I then reinstalled both using bundler
only.
A few commands I found useful:
gem info <gem>
bundle info <gem>
gem install/uninstall
(although usually better to use bundler if there's aGemfile
in the app directory)gem -v
bundle -v
bundle doctor
rbenv versions
gem update --system
In closing
My general strategy now for troubleshooting these installs is:
- Check version of Ruby is globally correct and make sure you haven't overridden this locally unless necessary
- Check I'm using latest versions of
bundle
andgem
- Remove all versions of the problematic app with
gem uninstall
- In the application directory (where the
Gemfile
is) runbundle
to install the app and its dependencies
Hope this helps!