Skip to content

Commit

Permalink
Merge pull request #1925 from Shopify/vs/fix_git_source_eager_loaded_…
Browse files Browse the repository at this point in the history
…rails_engines

Make Rails engine path check more specific
  • Loading branch information
vinistock committed Jun 14, 2024
2 parents e786469 + 6c1fe39 commit aaf1d32
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/tapioca/static/symbol_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def payload_symbols
sig { params(gem: Gemfile::GemSpec).returns(T::Set[String]) }
def engine_symbols(gem)
gem_engine = engines.find do |engine|
gem.contains_path?(engine.config.root.to_s)
gem.full_gem_path == engine.config.root.to_s
end

return Set.new unless gem_engine
Expand Down
57 changes: 57 additions & 0 deletions spec/tapioca/cli/gem_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,63 @@ class Application < Rails::Application
assert_empty_stderr(result)
assert_success_status(result)
end

it "properly filters eager loaded Rails engines when gem is installed from git source" do
# When Rails is installed through a release version, each gem contained inside `rails` is placed in a
# different sibling directory. However, when Rails is installed through a git source, all gems are placed
# nested under the Rails directory. When we check if an engine belongs to a gem, we need to take that into
# account to avoid placing symbols that do not belong to the Rails RBI inside of it
#
# Example of path for git installed Rails:
# /Users/me/.gem/ruby/3.3.0/bundler/gems/rails-e3ea4c74124f/
# /Users/me/.gem/ruby/3.3.0/bundler/gems/rails-e3ea4c74124f/activestorage
# /Users/me/.gem/ruby/3.3.0/bundler/gems/rails-e3ea4c74124f/actionmailbox
#
# The engines defined by `activestorage` and `actionmailbox` should not be placed in the Rails RBI. They
# belong in their own respective RBIs.
#
# Note that this problem only happens if another gem somehow eager loads the engines. By default, Rails
# would've not loaded those classes and they would have not been placed in the Rails RBI.

@project.write_gemfile!(<<~GEMFILE, append: true)
gem("rails", git: "https://github.com/rails/rails", branch: "main")
GEMFILE

# Create a gem that eager loads the ActionMailbox engine
gem = mock_gem("eager_loader", "1.0.0") do
write!("lib/eager_loader.rb", <<~RUBY)
require "action_mailbox/engine"
module EagerLoader
end
RUBY
end
@project.require_mock_gem(gem)

install_result = @project.bundle_install!
assert_predicate(install_result, :status, "Bundle install failed\n\n#{install_result.err}")

result = @project.tapioca("gem rails")
assert_empty_stderr(result)
assert_success_status(result)

assert_stdout_includes(result, "Compiled rails")
rails_rbi = T.must(Dir.glob("#{@project.absolute_path}/sorbet/rbi/gems/rails@*.rbi").first)

expected_rbi = <<~RBI
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `rails` gem.
# Please instead update this file by running `bin/tapioca gem rails`.
# THIS IS AN EMPTY RBI FILE.
# see https://github.com/Shopify/tapioca#manually-requiring-parts-of-a-gem
RBI

assert_equal(expected_rbi, File.read(rails_rbi))
end
end

describe "verify" do
Expand Down

0 comments on commit aaf1d32

Please sign in to comment.