Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# main [(unreleased)](https://github.com/fastruby/next_rails/compare/v1.4.4...main)

- [BUGFIX: example](https://github.com/fastruby/next_rails/pull/<number>)
- [Move rails_version compatibility to its own class](https://github.com/fastruby/next_rails/pull/137)

* Your changes/patches go here.

Expand Down
4 changes: 2 additions & 2 deletions exe/bundle_report
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ at_exit do
when "outdated" then NextRails::BundleReport.outdated(options.fetch(:format, nil))
else
if options[:ruby_version]
NextRails::BundleReport.compatibility(ruby_version: options.fetch(:ruby_version, "2.3"))
NextRails::BundleReport.ruby_compatibility(ruby_version: options.fetch(:ruby_version, "2.3"))
else
NextRails::BundleReport.compatibility(rails_version: options.fetch(:rails_version, "5.0"), include_rails_gems: options.fetch(:include_rails_gems, false))
NextRails::BundleReport.rails_compatibility(rails_version: options.fetch(:rails_version, "5.0"), include_rails_gems: options.fetch(:include_rails_gems, false))
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/next_rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require "next_rails/init"
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
67 changes: 8 additions & 59 deletions lib/next_rails/bundle_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,69 +8,18 @@ module NextRails
module BundleReport
extend self

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
def ruby_compatibility(ruby_version: nil)
return unless 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 }

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)
options = { ruby_version: ruby_version }
puts RubyVersionCompatibility.new(options: options).generate
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 rails_compatibility(rails_version: nil, include_rails_gems: nil)
return unless rails_version

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

def compatible_ruby_version(rails_version)
Expand Down
84 changes: 84 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,84 @@
class NextRails::BundleReport::RailsVersionCompatibility
def initialize(gems: NextRails::GemInfo.all, options: {})
@gems = gems
@options = options
end

def generate
erb_output
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

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
@incompatible_gems ||= @gems.reject do |gem|
gem.compatible_with_rails?(rails_version: rails_version) || (!include_rails_gems && gem.from_rails?)
end.sort_by { |gem| gem.name }
end

def rails_version
@options[:rails_version]
end

def include_rails_gems
@options[:include_rails_gems]
end
end
40 changes: 40 additions & 0 deletions spec/next_rails/bundle_report/rails_version_compatibility_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

require "spec_helper"

RSpec.describe NextRails::BundleReport::RailsVersionCompatibility do
describe "#generate" do
it "returns non incompatible gems" do
output = NextRails::BundleReport::RailsVersionCompatibility.new(options: { rails_version: 7.0 }).generate
expect(output).to match "gems incompatible with Rails 7.0"
end

it "returns incompatible with compatible versions" do
next_rails_version = 7.1
specification = Gem::Specification.new do |s|
s.name = "audited"
s.version = "5.1.0"
s.add_dependency "rails", ">= 5.0", "< 7.1"
end
audited = NextRails::GemInfo.new(specification)
gems = [audited]

allow_any_instance_of(described_class).to receive(:incompatible_gems_by_state)
.and_return({ found_compatible: gems })

allow(audited).to receive(:latest_compatible_version).and_return(Gem::Version.new("5.8.0"))

output =
NextRails::BundleReport::RailsVersionCompatibility.new(
gems: gems,
options: { rails_version: next_rails_version, include_rails_gems: false }
).generate

expect(output).to include("Incompatible with Rails 7.1 (with new versions that are compatible):")
expect(output).to include("These gems will need to be upgraded before upgrading to Rails 7.1.")
expect(output).to include("- upgrade to 5.8.0")
expect(output).to include("gems incompatible with Rails 7.1")
end
end
end

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# frozen_string_literal: true

require "spec_helper"
require "next_rails/bundle_report/ruby_version_compatibility"

RSpec.describe NextRails::BundleReport::RubyVersionCompatibility do
let(:ruby_3_0_gem) do
Expand Down
19 changes: 14 additions & 5 deletions spec/next_rails/bundle_report_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,21 @@
end
end

describe ".compatibility" do
describe "output" do
it "returns ERB generated output" do
output = NextRails::BundleReport.erb_output({}, [], 7.0)
expect(output).to match "gems incompatible with Rails 7.0"
describe ".rails_compatibility" do
it "returns empty output invalid rails version" do
output = with_captured_stdout do
NextRails::BundleReport.rails_compatibility(rails_version: nil)
end
expect(output).to be_empty
end
end

describe ".ruby_compatibility" do
it "returns empty output invalid ruby version" do
output = with_captured_stdout do
NextRails::BundleReport.ruby_compatibility(ruby_version: nil)
end
expect(output).to be_empty
end
end

Expand Down
9 changes: 9 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,12 @@
def with_env(env_hash)
stub_const("ENV", ENV.to_hash.merge!(env_hash))
end

def with_captured_stdout
old_stdout = $stdout
$stdout = StringIO.new
yield
$stdout.string
ensure
$stdout = old_stdout
end