Skip to content

Commit aaf1d32

Browse files
authored
Merge pull request #1925 from Shopify/vs/fix_git_source_eager_loaded_rails_engines
Make Rails engine path check more specific
2 parents e786469 + 6c1fe39 commit aaf1d32

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

lib/tapioca/static/symbol_loader.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def payload_symbols
2222
sig { params(gem: Gemfile::GemSpec).returns(T::Set[String]) }
2323
def engine_symbols(gem)
2424
gem_engine = engines.find do |engine|
25-
gem.contains_path?(engine.config.root.to_s)
25+
gem.full_gem_path == engine.config.root.to_s
2626
end
2727

2828
return Set.new unless gem_engine

spec/tapioca/cli/gem_spec.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,63 @@ class Application < Rails::Application
15051505
assert_empty_stderr(result)
15061506
assert_success_status(result)
15071507
end
1508+
1509+
it "properly filters eager loaded Rails engines when gem is installed from git source" do
1510+
# When Rails is installed through a release version, each gem contained inside `rails` is placed in a
1511+
# different sibling directory. However, when Rails is installed through a git source, all gems are placed
1512+
# nested under the Rails directory. When we check if an engine belongs to a gem, we need to take that into
1513+
# account to avoid placing symbols that do not belong to the Rails RBI inside of it
1514+
#
1515+
# Example of path for git installed Rails:
1516+
# /Users/me/.gem/ruby/3.3.0/bundler/gems/rails-e3ea4c74124f/
1517+
# /Users/me/.gem/ruby/3.3.0/bundler/gems/rails-e3ea4c74124f/activestorage
1518+
# /Users/me/.gem/ruby/3.3.0/bundler/gems/rails-e3ea4c74124f/actionmailbox
1519+
#
1520+
# The engines defined by `activestorage` and `actionmailbox` should not be placed in the Rails RBI. They
1521+
# belong in their own respective RBIs.
1522+
#
1523+
# Note that this problem only happens if another gem somehow eager loads the engines. By default, Rails
1524+
# would've not loaded those classes and they would have not been placed in the Rails RBI.
1525+
1526+
@project.write_gemfile!(<<~GEMFILE, append: true)
1527+
gem("rails", git: "https://github.com/rails/rails", branch: "main")
1528+
GEMFILE
1529+
1530+
# Create a gem that eager loads the ActionMailbox engine
1531+
gem = mock_gem("eager_loader", "1.0.0") do
1532+
write!("lib/eager_loader.rb", <<~RUBY)
1533+
require "action_mailbox/engine"
1534+
1535+
module EagerLoader
1536+
end
1537+
RUBY
1538+
end
1539+
@project.require_mock_gem(gem)
1540+
1541+
install_result = @project.bundle_install!
1542+
assert_predicate(install_result, :status, "Bundle install failed\n\n#{install_result.err}")
1543+
1544+
result = @project.tapioca("gem rails")
1545+
assert_empty_stderr(result)
1546+
assert_success_status(result)
1547+
1548+
assert_stdout_includes(result, "Compiled rails")
1549+
rails_rbi = T.must(Dir.glob("#{@project.absolute_path}/sorbet/rbi/gems/rails@*.rbi").first)
1550+
1551+
expected_rbi = <<~RBI
1552+
# typed: true
1553+
1554+
# DO NOT EDIT MANUALLY
1555+
# This is an autogenerated file for types exported from the `rails` gem.
1556+
# Please instead update this file by running `bin/tapioca gem rails`.
1557+
1558+
1559+
# THIS IS AN EMPTY RBI FILE.
1560+
# see https://github.com/Shopify/tapioca#manually-requiring-parts-of-a-gem
1561+
RBI
1562+
1563+
assert_equal(expected_rbi, File.read(rails_rbi))
1564+
end
15081565
end
15091566

15101567
describe "verify" do

0 commit comments

Comments
 (0)