diff --git a/lib/sorbet-rails/application_rbi_formatter.rb b/lib/sorbet-rails/application_rbi_formatter.rb new file mode 100644 index 00000000..c312df3f --- /dev/null +++ b/lib/sorbet-rails/application_rbi_formatter.rb @@ -0,0 +1,25 @@ +# typed: true +class ApplicationRbiFormatter + def initialize(rails_application_class_name) + @rails_application_class_name = rails_application_class_name + end + + def generate_rbi + puts "-- Generate sigs for Rails::Application --" + + <<~"RBI" + # This is an autogenerated file for your Rails::Application subclass + + # typed: strong + class #{@rails_application_class_name} < Rails::Application + end + + module Rails + extend T::Sig + + sig { returns(#{@rails_application_class_name}) } + def self.application; end + end + RBI + end +end diff --git a/lib/sorbet-rails/tasks/rails_rbi.rake b/lib/sorbet-rails/tasks/rails_rbi.rake index e6b41c39..5230a7bb 100644 --- a/lib/sorbet-rails/tasks/rails_rbi.rake +++ b/lib/sorbet-rails/tasks/rails_rbi.rake @@ -1,3 +1,4 @@ +require("sorbet-rails/application_rbi_formatter") require("sorbet-rails/model_rbi_formatter") require("sorbet-rails/routes_rbi_formatter") require("sorbet-rails/helper_rbi_formatter") @@ -9,6 +10,15 @@ require("sorbet-rails/utils") namespace :rails_rbi do + desc "Generate rbis for rails application" + task application: :environment do |t, args| + rails_application_class_name = Rails.application.class.name + formatter = ApplicationRbiFormatter.new(rails_application_class_name) + file_path = Rails.root.join("sorbet", "rails-rbi", "application.rbi") + FileUtils.mkdir_p(File.dirname(file_path)) + File.write(file_path, formatter.generate_rbi) + end + desc "Generate rbis for rails routes" task :routes, [:root_dir] => :environment do |t, args| all_routes = Rails.application.routes.routes diff --git a/spec/application_rbi_formatter_spec.rb b/spec/application_rbi_formatter_spec.rb new file mode 100644 index 00000000..1df04979 --- /dev/null +++ b/spec/application_rbi_formatter_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' +require 'sorbet-rails/application_rbi_formatter' + +RSpec.describe ApplicationRbiFormatter do + it 'returns the expected rbi for an application' do + formatter = ApplicationRbiFormatter.new(Rails.application.class.name) + expect_match_file( + formatter.generate_rbi, + 'expected_application.rbi' + ) + end +end diff --git a/spec/rake_rails_rbi_application_spec.rb b/spec/rake_rails_rbi_application_spec.rb new file mode 100644 index 00000000..a4607c10 --- /dev/null +++ b/spec/rake_rails_rbi_application_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +RSpec.describe 'rake rails_rbi:application', type: :task do + + it "preloads the Rails environment" do + expect(task.prerequisites).to include("environment") + end + + it "generates application.rbi correctly" do + task.invoke + expected_path = Rails.root.join("sorbet", "rails-rbi", "application.rbi") + generated = File.read(expected_path) + expect_match_file(generated, 'expected_application.rbi') + end +end diff --git a/spec/support/v4.2/config/application.rb b/spec/support/v4.2/config/application.rb index 804ae1eb..718c745e 100644 --- a/spec/support/v4.2/config/application.rb +++ b/spec/support/v4.2/config/application.rb @@ -16,7 +16,7 @@ # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) -module V42 +module Hogwarts_4_2 class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers diff --git a/spec/support/v5.0/config/application.rb b/spec/support/v5.0/config/application.rb index 89a6725f..88050669 100644 --- a/spec/support/v5.0/config/application.rb +++ b/spec/support/v5.0/config/application.rb @@ -17,7 +17,7 @@ # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) -module V50 +module Hogwarts_5_0 class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers diff --git a/spec/support/v5.1/config/application.rb b/spec/support/v5.1/config/application.rb index 5d2ac052..49df99c3 100644 --- a/spec/support/v5.1/config/application.rb +++ b/spec/support/v5.1/config/application.rb @@ -17,7 +17,7 @@ # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) -module RailsApp517 +module Hogwarts_5_17 class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 5.1 diff --git a/spec/support/v5.2-no-sorbet/config/application.rb b/spec/support/v5.2-no-sorbet/config/application.rb index 43a6ec9c..821b72df 100644 --- a/spec/support/v5.2-no-sorbet/config/application.rb +++ b/spec/support/v5.2-no-sorbet/config/application.rb @@ -18,7 +18,7 @@ # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) -module RailsApp +module Hogwarts_5_2_NoSorbet class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 5.2 diff --git a/spec/support/v5.2/config/application.rb b/spec/support/v5.2/config/application.rb index 43a6ec9c..4868cc6e 100644 --- a/spec/support/v5.2/config/application.rb +++ b/spec/support/v5.2/config/application.rb @@ -18,7 +18,7 @@ # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) -module RailsApp +module Hogwarts_5_2 class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 5.2 diff --git a/spec/support/v6.0/config/application.rb b/spec/support/v6.0/config/application.rb index 6c7e996c..d98aeecb 100644 --- a/spec/support/v6.0/config/application.rb +++ b/spec/support/v6.0/config/application.rb @@ -20,7 +20,7 @@ # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) -module V60 +module Hogwarts_6_0 class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 6.0 diff --git a/spec/test_data/v4.2/expected_application.rbi b/spec/test_data/v4.2/expected_application.rbi new file mode 100644 index 00000000..59598d6e --- /dev/null +++ b/spec/test_data/v4.2/expected_application.rbi @@ -0,0 +1,12 @@ +# This is an autogenerated file for your Rails::Application subclass + +# typed: strong +class Hogwarts_4_2::Application < Rails::Application +end + +module Rails + extend T::Sig + + sig { returns(Hogwarts_4_2::Application) } + def self.application; end +end diff --git a/spec/test_data/v5.0/expected_application.rbi b/spec/test_data/v5.0/expected_application.rbi new file mode 100644 index 00000000..f83063c0 --- /dev/null +++ b/spec/test_data/v5.0/expected_application.rbi @@ -0,0 +1,12 @@ +# This is an autogenerated file for your Rails::Application subclass + +# typed: strong +class Hogwarts_5_0::Application < Rails::Application +end + +module Rails + extend T::Sig + + sig { returns(Hogwarts_5_0::Application) } + def self.application; end +end diff --git a/spec/test_data/v5.1/expected_application.rbi b/spec/test_data/v5.1/expected_application.rbi new file mode 100644 index 00000000..4058bfe2 --- /dev/null +++ b/spec/test_data/v5.1/expected_application.rbi @@ -0,0 +1,12 @@ +# This is an autogenerated file for your Rails::Application subclass + +# typed: strong +class Hogwarts_5_17::Application < Rails::Application +end + +module Rails + extend T::Sig + + sig { returns(Hogwarts_5_17::Application) } + def self.application; end +end diff --git a/spec/test_data/v5.2-no-sorbet/expected_application.rbi b/spec/test_data/v5.2-no-sorbet/expected_application.rbi new file mode 100644 index 00000000..aecc42b1 --- /dev/null +++ b/spec/test_data/v5.2-no-sorbet/expected_application.rbi @@ -0,0 +1,12 @@ +# This is an autogenerated file for your Rails::Application subclass + +# typed: strong +class Hogwarts_5_2_NoSorbet::Application < Rails::Application +end + +module Rails + extend T::Sig + + sig { returns(Hogwarts_5_2_NoSorbet::Application) } + def self.application; end +end diff --git a/spec/test_data/v5.2/expected_application.rbi b/spec/test_data/v5.2/expected_application.rbi new file mode 100644 index 00000000..73731ab0 --- /dev/null +++ b/spec/test_data/v5.2/expected_application.rbi @@ -0,0 +1,12 @@ +# This is an autogenerated file for your Rails::Application subclass + +# typed: strong +class Hogwarts_5_2::Application < Rails::Application +end + +module Rails + extend T::Sig + + sig { returns(Hogwarts_5_2::Application) } + def self.application; end +end diff --git a/spec/test_data/v6.0/expected_application.rbi b/spec/test_data/v6.0/expected_application.rbi new file mode 100644 index 00000000..5140df3c --- /dev/null +++ b/spec/test_data/v6.0/expected_application.rbi @@ -0,0 +1,12 @@ +# This is an autogenerated file for your Rails::Application subclass + +# typed: strong +class Hogwarts_6_0::Application < Rails::Application +end + +module Rails + extend T::Sig + + sig { returns(Hogwarts_6_0::Application) } + def self.application; end +end