class Tapioca::Gemfile

def dir

def dir
  File.expand_path(gemfile.path + "/..")
end

def gem(gem_name)

def gem(gem_name)
  dependencies.detect { |dep| dep.name == gem_name }
end

def groups

def groups
  definition.groups
end

def initialize(excluded_gems)

def initialize(excluded_gems)
  @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)
  @excluded_gems = excluded_gems
  dependencies, missing_specs = load_dependencies
  @dependencies = T.let(dependencies, T::Array[GemSpec])
  @missing_specs = T.let(missing_specs, T::Array[String])
end

def load_dependencies

def load_dependencies
  materialized_dependencies, missing_specs = materialize_deps
  dependencies = materialized_dependencies
    .map { |spec| GemSpec.new(spec) }
    .reject { |gem| gem.ignore?(dir) }
    .uniq(&:rbi_file_name)
    .sort_by(&:rbi_file_name)
  [dependencies, missing_specs]
end

def materialize_deps

def materialize_deps
  deps = definition.locked_gems.dependencies.except(*@excluded_gems).values
  resolve = definition.resolve
  materialized_dependencies = resolve.materialize(deps)
  if Bundler::VERSION >= "2.6.0"
    missing_specs = resolve.missing_specs.map do |spec|
      "#{spec.name} (#{spec.version})"
    end
  else
    missing_spec_names = materialized_dependencies.missing_specs.map(&:name).to_set
    missing_specs = materialized_dependencies.missing_specs.map do |spec|
      "#{spec.name} (#{spec.version})"
    end
    materialized_dependencies = materialized_dependencies.to_a.reject do |spec|
      missing_spec_names.include?(spec.name)
    end
  end
  [materialized_dependencies, missing_specs]
end

def require_bundle

def require_bundle
  BundlerExt::AutoRequireHook.override_require_false(exclude: @excluded_gems) do
    T.unsafe(runtime).require(*groups)
  end
end

def runtime

def runtime
  Bundler::Runtime.new(File.dirname(gemfile.path), definition)
end