Better iOS Projects: Advanced Usages of 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.
June 11, 2018, by Wolfgang LutzDigging deeper with ruby
Updates
- 24. February 2021: Checked for validity, updated the deprecated use of
--binstubs
, minor text changes.
Special Note
You should not have to use root user permissions via sudo
for any of the calls 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.
Advanced Usages of rbenv
After we learnt to install and use rbenv and bundler in the previous post of the series “Better iOS Projects”, How to manage the ruby environment of your iOS Project using rbenv, we continue by having a look at some of the more advanced features and pitfalls of using rbenv and bundler.
How do I use bundler in ruby-scripts?
To ensure that the correct versions of gems are used inside a ruby script, you need to require rubygems and bundler/setup at the top of the script:
#!/usr/bin/ruby
# Non-Bundler Dependencies
require 'optparse'
require 'ostruct'
# Support for Bundler and Gems
require 'rubygems'
require 'bundler/setup'
# Now, the version of xcodeproj defined via Bundler is used
require 'xcodeproj'
Using binstubs
To ensure that all calls use the version defined in the Gemfile without prefixing the call with
bundle exec
, you can use the binstubs
command along with the gems to stub to the
installation command:
bundle binstubs fastlane
It is recommended to explicitly name the gems you want to stub to avoid conflicts with gems that deliver their own stubs, e.g. rake.
Then, you can call the command by prepending bin/
, e.g.
bin/fastlane
You can also add export PATH="./bin:$PATH"
to your shell’s rc file (see above) to always search the
bin folder (where binstubs are installed to) when running commands. This might have security implications though. If you do
this, it is enough to type
fastlane
As an alternative to binstubs, you can also add the alias alias be="bundle exec"
to your .rc file,
to
make the original call shorter:
be fastlane
Bonus: How to automate installing the correct ruby version and gems
At Number42, we always include a script called bootstrap.sh in our projects,
which
does the most basic setup calls needed to run the project afterwards. Whenever something does not work out of the
box after cloning (or pulling) a project, calling sh bootstrap.sh
is able to sort out the larger part
of problems in most cases. We use this the same way for iOS and web projects. We will have a closer look at the
bootstrap script in an upcoming episode of this series.
Among those are the installation of ruby, Bundler and Gems:
#!/bin/sh
# exit script on error
set -e
# define colors
RED=`tput setaf 1`
GREEN=`tput setaf 2`
NOCOLOR=`tput sgr0`
# Guard to update brew only once and only if necessary
NEEDS_TO_UPDATE_BREW=1
# Helper to install brew dependencies
installDependencyWithBrew(){
if [ $NEEDS_TO_UPDATE_BREW -eq 1 ]; then
echo ""
echo "${GREEN} UPDATING BREW ${NOCOLOR}";
# update brew to keep dependencies up to date
brew update || echo "${RED} FAILED TO UPDATE BREW ${NOCOLOR}";
NEEDS_TO_UPDATE_BREW=0
fi
echo ""
echo "${GREEN} INSTALLING $1 WITH BREW ${NOCOLOR}";
# install dependency, if is not installed
brew list $1 || brew install $1 || echo "${RED} FAILED TO INSTALL $1 ${NOCOLOR}";
# upgrade dependency, if it is outdated
brew outdated $1 || brew upgrade $1 || echo "${RED} FAILED TO UPGRADE $1 ${NOCOLOR}";
}
# Install ruby if a .ruby-version exists
if [ -e ".ruby-version" ]; then
echo ""
echo "${GREEN} SETTING UP RUBY ${NOCOLOR}";
installDependencyWithBrew rbenv
installDependencyWithBrew ruby-build
# install ruby version from .ruby-version, skipping if already installed (-s)
rbenv install -s
fi
# Install gems if a Gemfile exists
if [ -e "Gemfile" ]; then
echo ""
echo "${GREEN} INSTALLING GEMS ${NOCOLOR}";
# install bundler gem for ruby dependency management
gem install bundler --no-document || echo "${RED} FAILED TO INSTALL BUNDLER ${NOCOLOR}";
bundle install || echo "${RED} FAILED TO INSTALL BUNDLE ${NOCOLOR}";
fi
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, as always, to Melanie Kloss for the great banner image.