After six years of writing Rails apps, for clients as well as side projects (and not-so-side projects), I started seeing a clear pattern in my Gemfiles, namely a bunch of gems I used over and over again.
Well, actually I probably started seeing those patterns already on the third or fourth Rails app, but by now I can be fairly certain that there are some gems that I will want to use in every project I work on.
I used to define my gem dependencies very explicitly:
gem 'devise', '3.2.4'
I never liked the
~> syntax since I wanted to see in my Gemfile exactly which gem versions the app was using, and I didn't trust other developers to always use semantic versioning. :)
This meant that, when a new version of
devise was released for example, I had to go through all of my apps, find those that use
devise, and update the dependency one by one.
Now I realized most gems (the ones I include in my commons gems at least) do use semantic versioning and defining my gem dependencies using
~> actually has a lot of advantages.
So I started to pull out those common gems and put them in a separate Git repo. I add this repo as a Git submodule in each of my apps, and require the included Gemfiles in my project's Gemfile like so:
%w( common-gems/rails/Gemfile common-gems/redis/Gemfile # optional common-gems/sidekiq/Gemfile # optional common-gems/testing/Gemfile # optional ).each do |gemfile| instance_eval(File.read(gemfile)) end
So far this has served me very well, but if it becomes too cluttered or confusing I might revisit it in the future.
Would love to hear from other developers in the comments what they thing about this approach!