DEV Community

Cover image for How to use custom gems without changing the Gemfile
Povilas Jurčys
Povilas Jurčys

Posted on • Edited on

How to use custom gems without changing the Gemfile

Intro

It was a typical Tuesday. My warm coffee sat on the table, and my rubber duck was in front of me. I remembered that last week I had been investigating a bug and knew which method I needed to look into for troubleshooting. There was something wrong with one of the arguments.

I updated my branch, ran bundle install, and started the server. I put binding.pry in that method to check the argument. Sure enough, the argument wasn't supposed to reach the method I was investigating. I needed to find out who was calling this method and how the argument was being built. In the pry debug console, I typed up and suddenly got an undefined method "up" error.

Did I make a typo? No. But there had been some gem updates - maybe my favorite pry-byebug gem had major changes? I opened the Gemfile, and it was gone! I found a commit with the description "Do not use pry-byebug because it slows down the app." You know what - I'll take a slower app if it allows me to develop faster!

I’m sure you have your own stories about how certain development gems are considered a disadvantage for the project, even though they help you work more efficiently.

Well, I have good news for you - you can still use any gem you want in your development environment without changing the project codebase.

Gemfile.personal technique

The cleanest solution I've found is to use a separate Gemfile.personal and a custom Gemfile path. This way, you can use it in any project without modifying the project code at all.

1. Add the Gemfile.personal to the project's root directory

# /path/to/your_ruby_project/Gemfile.personal
eval File.read('Gemfile') # use all gems from Gemfile

gem 'personal-gem1'
gem 'personal-gem2'
Enter fullscreen mode Exit fullscreen mode

2. Install gems using the Gemfile.personal file

When installing gems, use the --gemfile option:

bundle install --gemfile=Gemfile.personal
Enter fullscreen mode Exit fullscreen mode

To keep Gemfile.personal.lock synchronized with Gemfile.lock, copy the contents of Gemfile.lock to Gemfile.personal.lock whenever you update your personal gems. Use the following script:

cp Gemfile.lock Gemfile.personal.lock && \
bundle install --gemfile=Gemfile.personal
Enter fullscreen mode Exit fullscreen mode

3. Globally ignore Gemfile.personal and Gemfile.personal.lock

touch ~/.gitignore
echo "Gemfile.personal\nGemfile.personal.lock" >> ~/.gitignore
git config --global core.excludesFile '~/.gitignore'
Enter fullscreen mode Exit fullscreen mode

This will apply to all projects, so you don't need to update each project's .gitignore separately.

**4. Update the BUNDLE_GEMFILE environment variable

If you want to use your custom Gemfile occasionally, you can include BUNDLE_GEMFILE=Gemfile.personal before every command, like this:

BUNDLE_GEMFILE=Gemfile.personal bundle exec rails console
Enter fullscreen mode Exit fullscreen mode

But I find that annoying. Instead, I use bash/zshell aliases to make my life easier:

# ~/.bashrc
alias be="bundle exec"

# The letter "c" stands for "custom"
alias bec="BUNDLE_GEMFILE=Gemfile.personal be"
Enter fullscreen mode Exit fullscreen mode

Now, I can switch Gemfiles by adding or removing one letter:

be rails console # uses the default Gemfile
bec rails console # uses Gemfile.personal
Enter fullscreen mode Exit fullscreen mode

However, this option is not for everyone. If you want to always use your custom Gemfile.personal, you could also set this value globally by adding this line at the end of your ~/.bashrc or ~/.zshrc file:

# ~/.bashrc or ~/.zshrc
export BUNDLE_GEMFILE=Gemfile.personal
Enter fullscreen mode Exit fullscreen mode

You could use a .env file to expose this variable per project:

# /path/to/your/project/.env
BUNDLE_GEMFILE=Gemfile.personal
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

Using the Gemfile.personal technique allows you to customize your development environment without affecting the rest of the team. It’s a flexible solution that keeps the project’s codebase unchanged while giving you the tools you need to work efficiently. With a few simple steps, you can set up your environment to include your preferred gems, making debugging and development smoother and faster. This approach ensures that your workflow remains uninterrupted and tailored to your preferences, all without impacting the project's performance or stability. Happy hacking!

Top comments (0)