Skip to content

Commit

Permalink
Do not force require excluded gems
Browse files Browse the repository at this point in the history
Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
  • Loading branch information
paracycle and Morriar committed Mar 2, 2022
1 parent 70f3700 commit ee595f6
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
2 changes: 1 addition & 1 deletion lib/tapioca/commands/gem.rb
Expand Up @@ -124,7 +124,7 @@ def loader

sig { returns(Gemfile) }
def bundle
@bundle ||= Gemfile.new
@bundle ||= Gemfile.new(@exclude)
end

sig { void }
Expand Down
37 changes: 31 additions & 6 deletions lib/tapioca/gemfile.rb
Expand Up @@ -21,16 +21,40 @@ class Gemfile
# `Bundler.require`.
module AutoRequireHook
extend T::Sig
extend T::Helpers

sig { void.checked(:never) }
requires_ancestor { ::Bundler::Dependency }

@exclude = T.let([], T::Array[String])

class << self
extend T::Sig

sig { params(exclude: T::Array[String]).returns(T::Array[String]) }
attr_writer :exclude

sig { params(name: T.untyped).returns(T::Boolean) }
def excluded?(name)
@exclude.include?(name)
end
end

sig { returns(T.untyped).checked(:never) }
def autorequire
value = super

# If the gem is excluded, we don't want to force require it, in case
# it has side-effects users don't want. For example, `fakefs` gem, if
# loaded, takes over filesystem operations.
return value if AutoRequireHook.excluded?(name)

# If a gem is marked as `require: false`, then its `autorequire`
# value will be `[]`. But, we want those gems to be loaded for our
# purposes as well, so we return `nil` in those cases, instead, which
# means `require: true`.
super.tap do |value|
return nil if value == []
end
return nil if value == []

value
end

::Bundler::Dependency.prepend(self)
Expand All @@ -45,8 +69,9 @@ def autorequire
sig { returns(T::Array[String]) }
attr_reader(:missing_specs)

sig { void }
def initialize
sig { params(exclude: T::Array[String]).void }
def initialize(exclude)
AutoRequireHook.exclude = exclude
@gemfile = T.let(File.new(Bundler.default_gemfile), File)
@lockfile = T.let(File.new(Bundler.default_lockfile), File)
@definition = T.let(Bundler::Dsl.evaluate(gemfile, lockfile, {}), Bundler::Definition)
Expand Down
16 changes: 15 additions & 1 deletion spec/tapioca/cli/gem_spec.rb
Expand Up @@ -484,19 +484,33 @@ class Foo::Secret; end
write("lib/foo/secret.rb", "class Foo::Secret; end")
end

bar = mock_gem("bar", "1.0.0") do
write("lib/bar.rb", <<~RUBY)
module Foo
MY_CONSTANT = 42
end
RUBY
end

@project.require_mock_gem(foo, require: false)
@project.require_mock_gem(bar, require: false)
@project.bundle_install

@project.write("sorbet/tapioca/require.rb", <<~RB)
require "foo/secret"
RB

result = @project.tapioca("gem foo")
result = @project.tapioca("gem --exclude bar")

refute_includes(result.out, <<~OUT)
Compiled bar
OUT

assert_includes(result.out, <<~OUT)
Compiled foo
OUT

refute_project_file_exist("sorbet/rbi/gems/bar@1.0.0.rbi")
assert_project_file_equal("sorbet/rbi/gems/foo@0.0.1.rbi", template(<<~RBI))
#{FOO_RBI.rstrip}
class Foo::Secret; end
Expand Down

0 comments on commit ee595f6

Please sign in to comment.