lib/tapioca/gemfile.rb in tapioca-0.7.3 vs lib/tapioca/gemfile.rb in tapioca-0.8.0
- old
+ new
@@ -14,21 +14,66 @@
::Bundler::StubSpecification,
::Gem::Specification
)
end
+ # This is a module that gets prepended to `Bundler::Dependency` and
+ # makes sure even gems marked as `require: false` are required during
+ # `Bundler.require`.
+ module AutoRequireHook
+ extend T::Sig
+ extend T::Helpers
+
+ 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`.
+ return nil if value == []
+
+ value
+ end
+
+ ::Bundler::Dependency.prepend(self)
+ end
+
sig { returns(Bundler::Definition) }
attr_reader(:definition)
sig { returns(T::Array[GemSpec]) }
attr_reader(:dependencies)
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)
dependencies, missing_specs = load_dependencies
@dependencies = T.let(dependencies, T::Array[GemSpec])
@@ -92,11 +137,12 @@
end
class GemSpec
extend(T::Sig)
- IGNORED_GEMS = T.let(["sorbet", "sorbet-static", "sorbet-runtime"].freeze, T::Array[String])
+ IGNORED_GEMS = T.let(["sorbet", "sorbet-static", "sorbet-runtime", "sorbet-static-and-runtime"].freeze,
+ T::Array[String])
sig { returns(String) }
attr_reader :full_gem_path, :version
sig { returns(T::Array[Pathname]) }
@@ -225,9 +271,10 @@
# To compensate for these cases, we walk up the directory hierarchy
# from the given file and try to match a <gem-name.gemspec> file in
# one of those folders to see if the path really belongs in the given gem
# or not.
return false unless Bundler::Source::Git === @spec.source
+
parent = Pathname.new(path)
until parent.root?
parent = parent.parent.expand_path
return true if parent.join("#{name}.gemspec").file?