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 LutzManaging 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.