Find dependencies blocking rails upgrades
The initial pain point when upgrading a rails app is figuring out which of your dependencies are blocking you upgrading the actual rails
gem (& immediate dependencies, actionpack, etc.). One way to start this is to update the rails dependency in your Gemfile
and run bundle update rails
. Then check the error output (it never works first time…) to see which gems are blocking the upgrade. Repeat, rinse until it works.
I figured I’d cheat a little and eyeball the Gemfile.lock
to see which gems had an explicit dependency pinning rails (or actionpack, activejob, etc) to a version lower than I want to upgrade to, so I could get an idea of what needs to be upgraded without having to do them all one-by-one.
Then instead of eyeballing Gemfile.lock
, I wrote an awk script to pull out the interesting dependencies (ie, anything that depends on rails gems) so I just have to check which versions they depend on by hand.
# Reads a Gemfile.lock and outputs all dependencies that depend on rails
BEGIN {
parent = 0
parent_printed = 0
rails_gems = "^(rail(s|ties)|action(mailer|pack|view)|active(job|model|record|support))$"
}
# We only want the specs from the GEM section
NR == 1, $1 ~ /GEM/ { next }
$1 == "" { exit }
# Skip parent gems we don't care about (rails itself…)
$0 ~ /^ {4}[^ ]/ &&
$1 ~ rails_gems {
parent = 0
parent_printed = 0
next
}
# Parent gems that aren't part of rails core
# Store the name to be printed if we match below
$0 ~ /^ {4}[^ ]/ {
parent = $0
parent_printed = 0
next
}
# If the nested gem (6 space prefix) matches rails-names and we have a parent value
# set then we print them out - making sure to only print the parent once
$0 ~ /^ {6}[^ ]/ &&
$1 ~ rails_gems &&
parent != 0 {
if (parent_printed == 0) {
parent_printed = 1
print parent
}
print $0
}
Run it against your Gemfile.lock
for the app you’re upgrading:
awk -f rails5.awk Gemfile.lock
And you’ll get output like this, to run through and see if any of the dependencies are pinning to lower versions than you need.
coffee-rails (4.0.1)
railties (>= 4.0.0, < 5.0)
factory_girl (4.4.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.4.1)
railties (>= 3.0.0)
globalid (0.3.7)
activesupport (>= 4.1.0)
google-api-client (0.8.6)
activesupport (>= 3.2)
jquery-rails (3.1.4)
railties (>= 3.0, < 5.0)
jquery-ui-rails (5.0.5)
railties (>= 3.2.16)
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.7)
activesupport (>= 4.2.0.beta, < 5.0)
rspec-rails (3.4.2)
actionpack (>= 3.0, < 4.3)
activesupport (>= 3.0, < 4.3)
railties (>= 3.0, < 4.3)
sass-rails (4.0.5)
railties (>= 4.0.0, < 5.0)
sprockets-rails (2.3.3)
actionpack (>= 3.0)
activesupport (>= 3.0)
In this case, I’m trying to take this app to rails 5.0, so all the ones specifying < 5
and < 4.3
need upgrading beforehand.