Skip to content

Commit

Permalink
Move bundle_report rails compatibility logic into a class
Browse files Browse the repository at this point in the history
I extracted it into a class because I think it will be easier to use the `incompatible_gems_by_state` data there.
  • Loading branch information
JuanVqz committed Feb 11, 2025
1 parent 8cdd756 commit 7f7a9df
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 60 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# main [(unreleased)](https://github.com/fastruby/next_rails/compare/v1.4.2...main)

- [Move rails_version compatibility to its own class](https://github.com/fastruby/next_rails/pull/137)
- [Add Ruby 3.4 support](https://github.com/fastruby/next_rails/pull/133)

* Your changes/patches go here.
Expand Down
1 change: 1 addition & 0 deletions lib/next_rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require "next_rails/version"
require "next_rails/bundle_report"
require "next_rails/bundle_report/ruby_version_compatibility"
require "next_rails/bundle_report/rails_version_compatibility"
require "deprecation_tracker"

module NextRails
Expand Down
61 changes: 2 additions & 59 deletions lib/next_rails/bundle_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,66 +11,9 @@ module BundleReport
def compatibility(rails_version: nil, ruby_version: nil, include_rails_gems: nil)
return puts RubyVersionCompatibility.new(options: { ruby_version: ruby_version }).generate if ruby_version

incompatible_gems = NextRails::GemInfo.all.reject do |gem|
gem.compatible_with_rails?(rails_version: rails_version) || (!include_rails_gems && gem.from_rails?)
end.sort_by { |gem| gem.name }
return unless rails_version

incompatible_gems.each { |gem| gem.find_latest_compatible(rails_version: rails_version) }

incompatible_gems_by_state = incompatible_gems.group_by { |gem| gem.state(rails_version) }

puts erb_output(incompatible_gems_by_state, incompatible_gems, rails_version)
end

def erb_output(incompatible_gems_by_state, incompatible_gems, rails_version)
template = <<-ERB
<% if incompatible_gems_by_state[:found_compatible] -%>
<%= Rainbow("=> Incompatible with Rails #{rails_version} (with new versions that are compatible):").white.bold %>
<%= Rainbow("These gems will need to be upgraded before upgrading to Rails #{rails_version}.").italic %>
<% incompatible_gems_by_state[:found_compatible].each do |gem| -%>
<%= gem_header(gem) %> - upgrade to <%= gem.latest_compatible_version.version %>
<% end -%>
<% end -%>
<% if incompatible_gems_by_state[:incompatible] -%>
<%= Rainbow("=> Incompatible with Rails #{rails_version} (with no new compatible versions):").white.bold %>
<%= Rainbow("These gems will need to be removed or replaced before upgrading to Rails #{rails_version}.").italic %>
<% incompatible_gems_by_state[:incompatible].each do |gem| -%>
<%= gem_header(gem) %> - new version, <%= gem.latest_version.version %>, is not compatible with Rails #{rails_version}
<% end -%>
<% end -%>
<% if incompatible_gems_by_state[:no_new_version] -%>
<%= Rainbow("=> Incompatible with Rails #{rails_version} (with no new versions):").white.bold %>
<%= Rainbow("These gems will need to be upgraded by us or removed before upgrading to Rails #{rails_version}.").italic %>
<%= Rainbow("This list is likely to contain internal gems, like Cuddlefish.").italic %>
<% incompatible_gems_by_state[:no_new_version].each do |gem| -%>
<%= gem_header(gem) %> - new version not found
<% end -%>
<% end -%>
<%= Rainbow(incompatible_gems.length.to_s).red %> gems incompatible with Rails <%= rails_version %>
ERB

erb_version = ERB.version
if erb_version =~ /erb.rb \[([\d\.]+) .*\]/
erb_version = $1
end

if Gem::Version.new(erb_version) < Gem::Version.new("2.2")
ERB.new(template, nil, "-").result(binding)
else
ERB.new(template, trim_mode: "-").result(binding)
end
end

def gem_header(_gem)
header = Rainbow("#{_gem.name} #{_gem.version}").bold
header << Rainbow(" (loaded from git)").magenta if _gem.sourced_from_git?
header
puts RailsVersionCompatibility.new(options: { rails_version: rails_version, include_rails_gems: include_rails_gems }).generate
end

def compatible_ruby_version(rails_version)
Expand Down
86 changes: 86 additions & 0 deletions lib/next_rails/bundle_report/rails_version_compatibility.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
class NextRails::BundleReport::RailsVersionCompatibility
def initialize(gems: NextRails::GemInfo.all, options: {})
@gems = gems
@options = options
end

def generate
erb_output
end

private

def erb_output
template = <<-ERB
<% if incompatible_gems_by_state[:found_compatible] -%>
<%= Rainbow("=> Incompatible with Rails #{rails_version} (with new versions that are compatible):").white.bold %>
<%= Rainbow("These gems will need to be upgraded before upgrading to Rails #{rails_version}.").italic %>
<% incompatible_gems_by_state[:found_compatible].each do |gem| -%>
<%= gem_header(gem) %> - upgrade to <%= gem.latest_compatible_version.version %>
<% end -%>
<% end -%>
<% if incompatible_gems_by_state[:incompatible] -%>
<%= Rainbow("=> Incompatible with Rails #{rails_version} (with no new compatible versions):").white.bold %>
<%= Rainbow("These gems will need to be removed or replaced before upgrading to Rails #{rails_version}.").italic %>
<% incompatible_gems_by_state[:incompatible].each do |gem| -%>
<%= gem_header(gem) %> - new version, <%= gem.latest_version.version %>, is not compatible with Rails #{rails_version}
<% end -%>
<% end -%>
<% if incompatible_gems_by_state[:no_new_version] -%>
<%= Rainbow("=> Incompatible with Rails #{rails_version} (with no new versions):").white.bold %>
<%= Rainbow("These gems will need to be upgraded by us or removed before upgrading to Rails #{rails_version}.").italic %>
<%= Rainbow("This list is likely to contain internal gems, like Cuddlefish.").italic %>
<% incompatible_gems_by_state[:no_new_version].each do |gem| -%>
<%= gem_header(gem) %> - new version not found
<% end -%>
<% end -%>
<%= Rainbow(incompatible_gems.length.to_s).red %> gems incompatible with Rails <%= rails_version %>
ERB

erb_version = ERB.version
if erb_version =~ /erb.rb \[([\d\.]+) .*\]/
erb_version = $1
end

if Gem::Version.new(erb_version) < Gem::Version.new("2.2")
ERB.new(template, nil, "-").result(binding)
else
ERB.new(template, trim_mode: "-").result(binding)
end
end

def gem_header(_gem)
header = Rainbow("#{_gem.name} #{_gem.version}").bold
header << Rainbow(" (loaded from git)").magenta if _gem.sourced_from_git?
header
end

def incompatible_gems_by_state
@incompatible_gems_by_state ||= begin
incompatible_gems.each { |gem| gem.find_latest_compatible(rails_version: rails_version) }
incompatible_gems.group_by { |gem| gem.state(rails_version) }
end
end

def incompatible_gems
@gems.reject { |gem| incompatible?(gem) }.sort_by(&:name)
end

def rails_version
@options[:rails_version]
end

def incompatible?(gem)
gem.compatible_with_rails?(rails_version: rails_version) || exclude_rails_gems?(gem)
end

def exclude_rails_gems?(gem)
!@options[:include_rails_gems] && gem.from_rails?
end
end
2 changes: 1 addition & 1 deletion spec/next_rails/bundle_report_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
describe ".compatibility" do
describe "output" do
it "returns ERB generated output" do
output = NextRails::BundleReport.erb_output({}, [], 7.0)
output = NextRails::BundleReport::RailsVersionCompatibility.new(options: { rails_version: 7.0 }).generate
expect(output).to match "gems incompatible with Rails 7.0"
end
end
Expand Down

0 comments on commit 7f7a9df

Please sign in to comment.