Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Add bundle_report compatibility --ruby-version report #116

Merged
merged 2 commits into from
Sep 9, 2024
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
Expand Up @@ -2,6 +2,7 @@

* Your changes/patches go here.

- [FEATURE: Support compatibility for Ruby versions](https://github.com/fastruby/next_rails/pull/116)
- [CHORE: Remove GPL licensed dependency Colorize and replace it with Rainbow]

# v1.3.0 / 2023-06-16 [(commits)](https://github.com/fastruby/next_rails/compare/v1.2.4...v1.3.0)
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,14 @@ bundle_report outdated --json
# Show gems that don't work with Rails 5.2.0
bundle_report compatibility --rails-version=5.2.0

# Show the usual help message
bundle_report --help
# Show gems that don't work with Ruby 3.0
bundle_report compatibility --ruby-version=3.0

# Find minimum compatible ruby version with Rails 7.0.0
bundle_report ruby_check --rails-version=7.0.0

# Show the usual help message
bundle_report --help
```

### Application usage
Expand Down
11 changes: 10 additions & 1 deletion exe/bundle_report
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ at_exit do

Examples:
#{$0} compatibility --rails-version 5.0
#{$0} compatibility --ruby-version 3.3
#{$0} outdated
#{$0} outdated --json

Expand All @@ -33,6 +34,10 @@ at_exit do
options[:rails_version] = rails_version
end

opts.on("--ruby-version [STRING]", "Ruby version to check compatibility against (defaults to 2.3)") do |ruby_version|
options[:ruby_version] = ruby_version
end

opts.on("--include-rails-gems", "Include Rails gems in compatibility report (defaults to false)") do
options[:include_rails_gems] = true
end
Expand Down Expand Up @@ -61,7 +66,11 @@ at_exit do
when "ruby_check" then NextRails::BundleReport.compatible_ruby_version(rails_version: options.fetch(:rails_version))
when "outdated" then NextRails::BundleReport.outdated(options.fetch(:format, nil))
else
NextRails::BundleReport.compatibility(rails_version: options.fetch(:rails_version, "5.0"), include_rails_gems: options.fetch(:include_rails_gems, false))
if options[:ruby_version]
NextRails::BundleReport.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))
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 @@ -3,6 +3,7 @@
require "next_rails/gem_info"
require "next_rails/version"
require "next_rails/bundle_report"
require "next_rails/bundle_report/ruby_version_compatibility"
require "deprecation_tracker"

module NextRails
Expand Down
4 changes: 3 additions & 1 deletion lib/next_rails/bundle_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ module NextRails
module BundleReport
extend self

def compatibility(rails_version: nil, include_rails_gems: nil)
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 }
Expand Down
44 changes: 44 additions & 0 deletions lib/next_rails/bundle_report/ruby_version_compatibility.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require "colorize"

class NextRails::BundleReport::RubyVersionCompatibility
MINIMAL_VERSION = 1.0
attr_reader :gems, :options

def initialize(gems: NextRails::GemInfo.all, options: {})
@gems = gems
@options = options
end

def generate
return invalid_message unless valid?

message
end

private

def message
output = "=> Incompatible gems with Ruby #{ruby_version}:".white.bold
incompatible.each do |gem|
output += "\n#{gem.name} - required Ruby version: #{gem.gem_specification.required_ruby_version}".magenta
end
output += "\n\n#{incompatible.length} incompatible #{incompatible.one? ? 'gem' : 'gems' } with Ruby #{ruby_version}".red
output
end

def incompatible
gems.reject { |gem| gem.compatible_with_ruby?(ruby_version) }
end

def ruby_version
options[:ruby_version].to_f
end

def invalid_message
"=> Invalid Ruby version: #{options[:ruby_version]}.".red.bold
end

def valid?
ruby_version > MINIMAL_VERSION
end
end
4 changes: 4 additions & 0 deletions lib/next_rails/gem_info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,5 +147,9 @@ def spec_compatible_with_rails?(specification: nil, rails_version: nil)
rails_dependency.requirement.satisfied_by?(Gem::Version.new(rails_version))
end
end

def compatible_with_ruby?(ruby_version)
gem_specification.required_ruby_version.satisfied_by?(Gem::Version.new(ruby_version))
end
end
end
86 changes: 86 additions & 0 deletions spec/next_rails/bundle_report/ruby_version_compatibility_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# 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
Gem::Specification.new do |s|
s.name = "ruby_3_0_gem"
s.version = "1.0.0"
s.required_ruby_version = ">= 3.0"
end
end

let(:ruby_2_5_gem) do
Gem::Specification.new do |s|
s.name = "ruby_2_5_gem"
s.version = "1.0.0"
s.required_ruby_version = ">= 2.5"
end
end

let(:ruby_2_3_to_2_5_gem) do
Gem::Specification.new do |s|
s.name = "ruby_2_3_to_2_5_gem"
s.version = "1.0.0"
s.required_ruby_version = [">= 2.3", "< 2.5"]
end
end

let(:no_ruby_version_gem) do
Gem::Specification.new do |s|
s.name = "no_ruby_version_gem"
s.version = "1.0.0"
end
end

describe "#generate" do
context "with invalid ruby version" do
it "returns invalid message" do
options = { ruby_version: "hola" }

result = described_class.new(gems: [], options: options).generate
expect(result).to include "Invalid Ruby version: hola"
end
end

context "with valid ruby version" do
it "returns 0 incompatible gems" do
options = { ruby_version: "3.0" }
gems = [NextRails::GemInfo.new(ruby_3_0_gem)]

result = described_class.new(gems: gems, options: options).generate
expect(result).to include "0 incompatible gems with Ruby 3.0"
end

it "returns 1 incompatible gem" do
options = { ruby_version: "2.5" }
gems = [NextRails::GemInfo.new(ruby_3_0_gem)]

result = described_class.new(gems: gems, options: options).generate

expect(result).to include "Incompatible gems with Ruby 2.5"
expect(result).to include "ruby_3_0_gem - required Ruby version: >= 3.0"
expect(result).to include "1 incompatible gem with Ruby 2.5"
end

it "returns 2 incompatible gems" do
options = { ruby_version: "2.7" }
gems = [
NextRails::GemInfo.new(ruby_3_0_gem),
NextRails::GemInfo.new(ruby_2_5_gem),
NextRails::GemInfo.new(ruby_2_3_to_2_5_gem),
NextRails::GemInfo.new(no_ruby_version_gem)
]

result = described_class.new(gems: gems, options: options).generate

expect(result).to include "Incompatible gems with Ruby 2.7"
expect(result).to include "ruby_3_0_gem - required Ruby version: >= 3.0"
expect(result).to include "ruby_2_3_to_2_5_gem - required Ruby version:" # >= 2.3, < 2.5"
expect(result).to include "2 incompatible gems with Ruby 2.7"
end
end
end
end
Loading