Made by Nathan

programming and projects

Automatically Run 'Bundle Install' When Bundler Can't Find a Gem

| Comments

Every Rails developer has probably experienced the following error:

Could not find <gem> in any of the sources
Run `bundle install` to install missing gems.

This happens if you or someone else adds a gem to your Gemfile, or if a gem version is updated in Gemfile.lock, and you forget to run bundle install before running a Rails command.

Here’s a simple function that handles this automatically, called bundle_install_wrapper(). It first tries to execute the command you pass to it. However, if Bundler exits with status code 7 (GemNotFound), then it will run bundle install. Finally, it retries the original command.

bundle_install_wrapper() {
  # Run command
  eval "$@"
  if [ $? = 7 ]; then
    # If command crashes, try a bundle install
    echo -e "\033[1;31m'$@' failed with exit code 7."
    echo    "This probably means that your system is missing gems defined in your Gemfile."
    echo -e "Executing 'bundle install'...\033[0m"
    bundle install
    # If bundle install was successful, try running command again.
    if [ $? = 0 ]; then
      echo "'bundle install' was successful. Retrying '$@'..."
      eval "$@"
    fi
  fi
}

Usage

Drop the function in your ~/.bashrc, and add aliases for rails commands:

alias rs="bundle_install_wrapper rails server"
alias rc="bundle_install_wrapper rails console"
# etc.

If you want aliases that support any Rails application, you can use something like this:

# Run Rails commands on any version
rails_cmd(){
  # Rails 3
  if [ -e ./script/rails ]; then bundle_install_wrapper rails3_with_editor $@
  # Rails <= 2
  elif [ -e ./script/$1 ]; then bundle_install_wrapper ./script/$@
  # Rails 4
  elif [ -e ./config.ru ] && grep -q Rails config.ru; then bundle_install_wrapper rails $@
  else echo "== I don't think this is a Rails application!"
  fi
}
alias   rs="rails_cmd server"
alias  rsd="rails_cmd server -u"
alias   rc="rails_cmd console"
alias   rg="rails_cmd generate"

See the Ruby on Rails section in my .bashrc if you’re interested in more aliases, and please leave a comment if you have any tips to share.

Comments