From 7f7a9df5234aae5abab4bff1c287e30db02e99fb Mon Sep 17 00:00:00 2001 From: Juan Vasquez Date: Tue, 11 Feb 2025 15:03:03 -0600 Subject: [PATCH] Move bundle_report rails compatibility logic into a class I extracted it into a class because I think it will be easier to use the `incompatible_gems_by_state` data there. --- CHANGELOG.md | 1 + lib/next_rails.rb | 1 + lib/next_rails/bundle_report.rb | 61 +------------ .../rails_version_compatibility.rb | 86 +++++++++++++++++++ spec/next_rails/bundle_report_spec.rb | 2 +- 5 files changed, 91 insertions(+), 60 deletions(-) create mode 100644 lib/next_rails/bundle_report/rails_version_compatibility.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index a3b3708..18bd17a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/lib/next_rails.rb b/lib/next_rails.rb index 7da5a14..734e09d 100644 --- a/lib/next_rails.rb +++ b/lib/next_rails.rb @@ -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 diff --git a/lib/next_rails/bundle_report.rb b/lib/next_rails/bundle_report.rb index 771035c..1a55f9f 100644 --- a/lib/next_rails/bundle_report.rb +++ b/lib/next_rails/bundle_report.rb @@ -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) diff --git a/lib/next_rails/bundle_report/rails_version_compatibility.rb b/lib/next_rails/bundle_report/rails_version_compatibility.rb new file mode 100644 index 0000000..dd7f2a8 --- /dev/null +++ b/lib/next_rails/bundle_report/rails_version_compatibility.rb @@ -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 diff --git a/spec/next_rails/bundle_report_spec.rb b/spec/next_rails/bundle_report_spec.rb index e159a7a..d20f4b4 100644 --- a/spec/next_rails/bundle_report_spec.rb +++ b/spec/next_rails/bundle_report_spec.rb @@ -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