Skip to content

Adds BundleReport CLI class to an entry point from executable file #154

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

Merged
merged 13 commits into from
May 6, 2025
Merged
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.6...main)

- [BUGFIX: example](https://github.com/fastruby/next_rails/pull/<number>)
- [CHORE: Create an entry point for the BundleReport command](https://github.com/fastruby/next_rails/pull/154)

* Your changes/patches go here.

Expand Down
76 changes: 2 additions & 74 deletions exe/bundle_report
Original file line number Diff line number Diff line change
@@ -1,78 +1,6 @@
#!/usr/bin/env ruby
#
# Print a report on our Gemfile
# Why not just use `bundle outdated`? It doesn't give us the information we care about (and it fails).
#
at_exit do
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there an specific reason for using this at_exit block?
I removed it from def run in the CLI because it was making tests execution fail for it

require "optparse"
require "next_rails"

options = {}
option_parser = OptionParser.new do |opts|
opts.banner = <<-EOS
Usage: #{$0} [report-type] [options]

report-type There are two report types available: `outdated` and `compatibility`

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

ruby_check To find a compatible ruby version for the target rails version

Examples:
#{$0} ruby_check --rails-version 7.0.0

EOS

opts.separator ""
opts.separator "Options:"

opts.on("--rails-version [STRING]", "Rails version to check compatibility against (defaults to 5.0)") do |rails_version|
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

opts.on("--json", "Output JSON in outdated report (defaults to false)") do
options[:format] = 'json'
end

opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end
end

begin
option_parser.parse!
rescue OptionParser::ParseError => e
STDERR.puts Rainbow(e.message).red
puts option_parser
exit 1
end

report_type = ARGV.first

case report_type
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
if options[:ruby_version]
NextRails::BundleReport.ruby_compatibility(ruby_version: options.fetch(:ruby_version, "2.3"))
else
NextRails::BundleReport.rails_compatibility(rails_version: options.fetch(:rails_version, "5.0"), include_rails_gems: options.fetch(:include_rails_gems, false))
end
end
end

# Needs to happen first
require "bundler/setup"
require "next_rails"
NextRails::BundleReport::CLI.new(ARGV).run
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/init"
require "next_rails/bundle_report"
require "next_rails/bundle_report/cli"
require "next_rails/bundle_report/ruby_version_compatibility"
require "next_rails/bundle_report/rails_version_compatibility"
require "deprecation_tracker"
Expand Down
117 changes: 117 additions & 0 deletions lib/next_rails/bundle_report/cli.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# frozen_string_literal: true

require "optparse"
require "next_rails"
require "next_rails/bundle_report"

class NextRails::BundleReport::CLI
def initialize(argv)
validate_arguments(argv)
@argv = argv
end

def validate_arguments(argv)
return unless argv.any?

valid_report_types = %w[outdated compatibility ruby_check]
report_type = argv.first

unless valid_report_types.include?(report_type)
raise ArgumentError, "Invalid report type '#{report_type}'. Valid types are: #{valid_report_types.join(', ')}."
end

argv.each do |arg|
if arg.start_with?("--rails-version") && !arg.match?(/--rails-version=+\d+(\.\d+)*$/)
raise ArgumentError, "Invalid Rails version format. Example: --rails-version=5.0.7"
end

if arg.start_with?("--ruby-version") && !arg.match?(/--ruby-version=+\d+(\.\d+)*$/)
raise ArgumentError, "Invalid Ruby version format. Example: --ruby-version=3.3"
end
end
end

def run
options = parse_options
execute_report(@argv.first, options)
end

private

def parse_options
options = {}
option_parser = OptionParser.new do |opts|
opts.banner = <<-EOS
Usage: #{$0} [report-type] [options]

report-type There are three report types available: `outdated`, `compatibility` and `ruby_check`.

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

ruby_check To find a compatible ruby version for the target rails version

Examples:
#{$0} ruby_check --rails-version 7.0.0

EOS

opts.separator ""
opts.separator "Options:"

opts.on("--rails-version [STRING]",
"Rails version to check compatibility against (defaults to 5.0)") do |rails_version|
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

opts.on("--json", "Output JSON in outdated report (defaults to false)") do
options[:format] = "json"
end

opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end
end

begin
option_parser.parse!(@argv)
rescue OptionParser::ParseError => e
warn Rainbow(e.message).red
puts option_parser
exit 1
end

options
end

def execute_report(report_type, options)
case report_type
when "ruby_check"
NextRails::BundleReport.compatible_ruby_version(rails_version: options.fetch(:rails_version))
when "outdated"
NextRails::BundleReport.outdated(options.fetch(:format, nil))
else
if options[:ruby_version]
NextRails::BundleReport.ruby_compatibility(ruby_version: options.fetch(:ruby_version, "2.3"))
else
NextRails::BundleReport.rails_compatibility(
rails_version: options.fetch(:rails_version, "5.0"),
include_rails_gems: options.fetch(:include_rails_gems, false)
)
end
end
end
end
36 changes: 36 additions & 0 deletions spec/next_rails/bundle_report/cli_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require "spec_helper"

RSpec.describe NextRails::BundleReport::CLI do
describe '#initialize' do
it 'calls with called with any arguemnt' do
expect(NextRails::BundleReport).to receive(:rails_compatibility)
described_class.new([]).run
end

it 'raises if called with invalid arguments' do
expect { described_class.new(['invalid_report_type']) }
.to raise_error(ArgumentError,
/Invalid report type 'invalid_report_type'. Valid types are: outdated, compatibility, ruby_check./)
end

it "calls outdated if called with outdated" do
expect(NextRails::BundleReport).to receive(:outdated)
described_class.new(["outdated"]).run
end

it "calls compatible_ruby_version if called with ruby_check" do
expect(NextRails::BundleReport).to receive(:compatible_ruby_version)
described_class.new(["ruby_check", "--rails-version=8.0.0"]).run
end

it 'calls rails_compatibility if called with compatibility with rails-version option' do
expect(NextRails::BundleReport).to receive(:rails_compatibility)
described_class.new(["compatibility", "--rails-version=8.0.0"]).run
end

it 'calls ruby_compatibility if called with compatibility with ruby-version option' do
expect(NextRails::BundleReport).to receive(:ruby_compatibility)
described_class.new(["compatibility", "--ruby-version=3.4.0"]).run
end
end
end