Better iOS projects: How to manage the ruby environment of your iOS project using rbenv

In the series "Better iOS projects", we have a look at the various tools and environments that are useful to have a more convenient and efficient handling of iOS Projects.

Mai 22, 2018, by Wolfgang Lutz

Managing rubies is easier with rbenv Managing rubies is easier with rbenv.

Special Note

You should not have to use root user permissions via sudo for any of the installs that follow. If you seem to need to, you most likely already had a permission problem before or you did not install and setup rbenv correctly.

How to manage the ruby environment of your iOS Project using rbenv

Why do we want to do this?

ruby has been used to program and run a variety of iOS development tools, such as fastlane, cocoapods or xcodeproj.

macOS comes with an older version of ruby preinstalled by default. As the system uses ruby itself, it is best practice not to mess around with the system ruby and use a user-installed (and more up-to-date) version of the ruby language. A ruby version manager allows you to maintain multiple installs of different ruby versions at the same time and decide per project (automatically via the .ruby-version file) which version of ruby you want to use.

A glossary of tools and filenames used in this article is available at the end of this article.

Which ruby environment manager should I use?

We have a smooth experience using rbenv, but you should be able to get similar results using rvm or chruby.

Install and setup rbenv

install brew

rbenv can easily be installed using the brew package manager, so make sure you have it installed and running.

install rbenv and ruby-build using brew

Install rbenv (for managing ruby environments) by running

brew install rbenv
    

this will also install ruby-build tool (for installing versions of ruby via rbenv)

If you are upgrading run

brew upgrade rbenv ruby-build
    

setup rbenv for your shell

After installing the tools above, you need to add a call to setup rbenv to your shell's configuration script.

You can find out which shell you are using by calling

echo $0
    

Depending on the result, you need to either change _~/.bash_profile (for bash), ~/.zshrc_ (for zsh) or the corresponding file of your shell if you have another shell.

If the file (e.g. _~/.bash_profile_) does not exist before, just create it.

As we use the very good Oh-My-ZSH as shell, we can edit it by opening ~/.zshrc in a graphical text editor or edit it directly in the shell by calling

nano ~/.zshrc
    

Add

eval "$(rbenv init -)"
    

to the end of the file and save it, then quit your terminal application and reopen it to make sure the changes are applied.

rbenv commands

rbenv has various commands, which should be listed when you run

rbenv help
    

The most important for us in the scope of this article are:

rbenv version

This shows the current ruby version set via rbenv. By default, this should show system. It also shows you the path to the file that is responsible for selecting the version.

rbenv versions

This lists all versions of ruby installed via rbenv (and the system version).

rbenv install

Installs a specific version of ruby. You can look up the newest version of ruby at ruby-lang.org.

Also, rbenv install -l shows you a list of versions available to ruby-build. If you are missing a version, upgrade ruby-build by running brew upgrade rbenv ruby-build.

rbenv local

This shows or sets the version defined for the current directory and its subdirectories.

rbenv rehash

This can become handy if you have trouble using a gem after having it installed, as it updates the underpinnings of rbenv.

Debugging

rbenv which and rbenv whence are useful if you have issues when using ruby via rbenv and something does not work as expected.

Install a custom ruby and create the .ruby-version file

Start by installing the newest version, which is 2.5.1 at the time of this post:

rbenv install 2.5.1
    

See https://www.ruby-lang.org/en/downloads/ for the most recent version.

If there already is a .ruby-version file, run

rbenv install
    

without any version argument to install the version set in the .ruby-version file.

Enter your iOS project directory and run

rbenv local 2.5.1
    

to create a .ruby-version file with the content 2.5.1.

rbenv local will only do this, if the version is already installed.

After restarting the terminal (or entering the parent directory and reentering the directory), running rbenv version should give you the version 2.5.1 if everything worked correctly.

How to use Bundler

What is Bundler?

bundler is a dependency manager for ruby, as cocoapods is for the iOS ecosystem. It can ensure that a defined set of dependencies is installed with the exact version of dependencies (gems) that was used when the dependencies where updated the last time.

How to install bundler

For every ruby version installed via rbenv, you have to once run

gem install bundler
    

to install the dependency manager.

What files does Bundler use?

Bundler defines dependencies using a Gemfile.

This defines, what gems (and possibly: what versions) you want to have installed:

# List of gems used in this project
    gem "cocoapods", "~> 1.5"
    

When updating gems (or adding them to the project), the exact version of the gem that will be installed is written to a file named Gemfile.lock.

Adding and updating gems

When you do not have a Gemfile yet, you can create one by running

bundle init
    

To add a first dependency, you can run bundle add <Gemname>, e.g.

bundle add fastlane
    

This adds the dependency to the Gemfile and installs the new dependency.

Running

bundle install
    

resolves the dependency graph in the Gemfile, installs the dependencies and writes the resolved versions to the Gemfile.lock file. This is important if you edit the Gemfile by hand.

You should now be able to run

bundle exec fastlane
    

if everything went right.

To sync the dependencies across the developers of the project, it is important to commit both Gemfile and Gemfile.lock to your project.

When do I need to run bundle install and bundle update?

Generally, you only need to run bundle update if you really intend to upgrade the versions of your gems. When you check out a project and want to get it to build, it is sufficient to run bundle install most of the time.

Where to go from here?

Install and properly manage the gems your project needs and at least teach your team how to install new ruby versions via rbenv and gems via bundle.

In the next post of the "Better iOS Projects" series, we have a look at some advanced features of rbenv.

Glossary

  • .ruby-version: a simple file that defines, what version of ruby you want to use for the project
  • bash: The default shell for most Linux and UNIX systems, see BASH
  • bundler: the ruby dependency manager
  • gem: a ruby dependency
  • Gemfile: the definition file, where all the dependencies are listed that bundler should install
  • Gemfile.lock: the file, where bundler saves the exact versions of all dependencies and their dependencies, as resolved during install
  • oh-my-zsh: a collection of configurations and scripts for zsh
  • rbenv: a tool to manage multiple versions of ruby on the same computer
  • ruby-build: a tool to install ruby versions
  • ruby: a programming language
  • zsh: the Z Shell

Acknowledgments

Thanks to Melanie Kloss for the great banner image.

Everything from the series 'Better iOS Projects':