Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/tapioca/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def dsl(*constants)
only: options[:only],
exclude: options[:exclude],
file_header: options[:file_header],
compiler_path: Tapioca::Dsl::Compilers::DIRECTORY,
compilers_path: Tapioca::Dsl::Compilers::DIRECTORY,
tapioca_path: TAPIOCA_DIR,
should_verify: options[:verify],
quiet: options[:quiet],
Expand Down
65 changes: 8 additions & 57 deletions lib/tapioca/commands/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Dsl < Command
only: T::Array[String],
exclude: T::Array[String],
file_header: T::Boolean,
compiler_path: String,
compilers_path: String,
tapioca_path: String,
should_verify: T::Boolean,
quiet: T::Boolean,
Expand All @@ -31,7 +31,7 @@ def initialize(
only:,
exclude:,
file_header:,
compiler_path:,
compilers_path:,
tapioca_path:,
should_verify: false,
quiet: false,
Expand All @@ -46,7 +46,7 @@ def initialize(
@only = only
@exclude = exclude
@file_header = file_header
@compiler_path = compiler_path
@compilers_path = compilers_path
@tapioca_path = tapioca_path
@should_verify = should_verify
@quiet = quiet
Expand All @@ -57,16 +57,15 @@ def initialize(
@rbi_formatter = rbi_formatter

super()

@loader = T.let(nil, T.nilable(Runtime::Loader))
end

sig { override.void }
def execute
load_dsl_extensions
load_application(eager_load: @requested_constants.empty?)
abort_if_pending_migrations!
load_dsl_compilers
Loaders::Dsl.load_application(
tapioca_path: @tapioca_path,
compilers_path: @compilers_path,
eager_load: @requested_constants.empty?
)

if @should_verify
say("Checking for out-of-date RBIs...")
Expand Down Expand Up @@ -131,44 +130,6 @@ def execute

private

sig { params(eager_load: T::Boolean).void }
def load_application(eager_load:)
say("Loading Rails application... ")

loader.load_rails_application(
environment_load: true,
eager_load: eager_load
)

say("Done", :green)
end

sig { void }
def abort_if_pending_migrations!
return unless File.exist?("config/application.rb")
return unless defined?(::Rake)

Rails.application.load_tasks
if Rake::Task.task_defined?("db:abort_if_pending_migrations")
Rake::Task["db:abort_if_pending_migrations"].invoke
end
end

sig { void }
def load_dsl_compilers
say("Loading DSL compiler classes... ")

Dir.glob([
"#{@compiler_path}/*.rb",
"#{@tapioca_path}/generators/**/*.rb", # TODO: Here for backcompat, remove later
"#{@tapioca_path}/compilers/**/*.rb",
]).each do |compiler|
require File.expand_path(compiler)
end

say("Done", :green)
end

sig { params(requested_constants: T::Array[String], path: Pathname).returns(T::Set[Pathname]) }
def existing_rbi_filenames(requested_constants, path: @outpath)
filenames = if requested_constants.empty?
Expand Down Expand Up @@ -354,11 +315,6 @@ def rbi_files_in(path)
end.sort
end

sig { returns(Runtime::Loader) }
def loader
@loader ||= Runtime::Loader.new
end

sig { params(class_name: String).returns(String) }
def underscore(class_name)
return class_name unless /[A-Z-]|::/.match?(class_name)
Expand All @@ -380,11 +336,6 @@ def rbi_filename_for(constant)
def generate_command_for(constant)
default_command(:dsl, constant)
end

sig { void }
def load_dsl_extensions
Dir["#{__dir__}/../dsl/extensions/*.rb"].sort.each { |f| require(f) }
end
end
end
end
70 changes: 19 additions & 51 deletions lib/tapioca/commands/gem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ def initialize(

super()

@loader = T.let(nil, T.nilable(Runtime::Loader))
@bundle = T.let(nil, T.nilable(Gemfile))
@bundle = T.let(Gemfile.new(exclude), Gemfile)
@existing_rbis = T.let(nil, T.nilable(T::Hash[String, String]))
@expected_rbis = T.let(nil, T.nilable(T::Hash[String, String]))
@include_doc = T.let(include_doc, T::Boolean)
Expand All @@ -66,7 +65,12 @@ def initialize(

sig { override.void }
def execute
require_gem_file
Loaders::Gem.load_application(
bundle: @bundle,
prerequire: @prerequire,
postrequire: @postrequire,
default_command: default_command(:require),
)

gem_queue = gems_to_generate(@gem_names).reject { |gem| @exclude.include?(gem.name) }
anything_done = [
Expand All @@ -87,7 +91,7 @@ def execute
gem_dir: @outpath.to_s,
dsl_dir: @dsl_dir,
auto_strictness: @auto_strictness,
gems: bundle.dependencies
gems: @bundle.dependencies
)

say("All operations performed in working directory.", [:green, :bold])
Expand Down Expand Up @@ -117,7 +121,7 @@ def sync(should_verify: false, exclude: [])
gem_dir: @outpath.to_s,
dsl_dir: @dsl_dir,
auto_strictness: @auto_strictness,
gems: bundle.dependencies
gems: @bundle.dependencies
)

say("All operations performed in working directory.", [:green, :bold])
Expand All @@ -131,42 +135,12 @@ def sync(should_verify: false, exclude: [])

private

sig { returns(Runtime::Loader) }
def loader
@loader ||= Runtime::Loader.new
end

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

sig { void }
def require_gem_file
say("Requiring all gems to prepare for compiling... ")
begin
loader.load_bundle(bundle, @prerequire, @postrequire)
rescue LoadError => e
explain_failed_require(@postrequire, e)
exit(1)
end

Runtime::Trackers::Autoload.eager_load_all!

say(" Done", :green)
unless bundle.missing_specs.empty?
say(" completed with missing specs: ")
say(bundle.missing_specs.join(", "), :yellow)
end
puts
end

sig { params(gem_names: T::Array[String]).returns(T::Array[Gemfile::GemSpec]) }
def gems_to_generate(gem_names)
return bundle.dependencies if gem_names.empty?
return @bundle.dependencies if gem_names.empty?

gem_names.map do |gem_name|
gem = bundle.gem(gem_name)
gem = @bundle.gem(gem_name)
if gem.nil?
say("Error: Cannot find gem '#{gem_name}'", :red)
exit(1)
Expand Down Expand Up @@ -263,7 +237,12 @@ def perform_additions
if gems.empty?
say("Nothing to do.")
else
require_gem_file
Loaders::Gem.load_application(
bundle: @bundle,
prerequire: @prerequire,
postrequire: @postrequire,
default_command: default_command(:require),
)

Executor.new(gems, number_of_workers: @number_of_workers).run_in_parallel do |gem_name|
filename = expected_rbi(gem_name)
Expand All @@ -273,7 +252,7 @@ def perform_additions
move(old_filename, filename) unless old_filename == filename
end

gem = T.must(bundle.gem(gem_name))
gem = T.must(@bundle.gem(gem_name))
compile_gem_rbi(gem)
puts
end
Expand All @@ -287,17 +266,6 @@ def perform_additions
anything_done
end

sig { params(file: String, error: LoadError).void }
def explain_failed_require(file, error)
say_error("\n\nLoadError: #{error}", :bold, :red)
say_error("\nTapioca could not load all the gems required by your application.", :yellow)
say_error("If you populated ", :yellow)
say_error("#{file} ", :bold, :blue)
say_error("with ", :yellow)
say_error("`#{default_command(:require)}`", :bold, :blue)
say_error("you should probably review it and remove the faulty line.", :yellow)
end

sig { returns(T::Array[String]) }
def removed_rbis
(existing_rbis.keys - expected_rbis.keys).sort
Expand Down Expand Up @@ -359,7 +327,7 @@ def existing_rbis

sig { returns(T::Hash[String, String]) }
def expected_rbis
@expected_rbis ||= bundle.dependencies
@expected_rbis ||= @bundle.dependencies
.reject { |gem| @exclude.include?(gem.name) }
.to_h { |gem| [gem.name, gem.version.to_s] }
end
Expand Down
5 changes: 4 additions & 1 deletion lib/tapioca/internal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

require "tapioca/runtime/dynamic_mixin_compiler"
require "tapioca/helpers/gem_helper"
require "tapioca/runtime/loader"

require "tapioca/helpers/sorbet_helper"
require "tapioca/helpers/rbi_helper"
Expand All @@ -50,6 +49,10 @@
require "tapioca/static/symbol_loader"
require "tapioca/static/requires_compiler"

require "tapioca/loaders/loader"
require "tapioca/loaders/gem"
require "tapioca/loaders/dsl"

require "tapioca/gem"
require "tapioca/dsl"
require "tapioca/commands"
Expand Down
78 changes: 78 additions & 0 deletions lib/tapioca/loaders/dsl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# typed: strict
# frozen_string_literal: true

module Tapioca
module Loaders
class Dsl < Loader
extend T::Sig

sig { params(tapioca_path: String, compilers_path: String, eager_load: T::Boolean).void }
def self.load_application(tapioca_path:, compilers_path:, eager_load: true)
loader = new(tapioca_path: tapioca_path, compilers_path: compilers_path)
loader.load
end

sig { override.void }
def load
load_dsl_extensions
load_application
abort_if_pending_migrations!
load_dsl_compilers
end

protected

sig { params(tapioca_path: String, compilers_path: String, eager_load: T::Boolean).void }
def initialize(tapioca_path:, compilers_path:, eager_load: true)
super()

@tapioca_path = tapioca_path
@compilers_path = compilers_path
@eager_load = eager_load
end

sig { void }
def load_dsl_extensions
Dir["#{__dir__}/../dsl/extensions/*.rb"].sort.each { |f| require(f) }
end

sig { void }
def load_dsl_compilers
say("Loading DSL compiler classes... ")

Dir.glob([
"#{@compilers_path}/*.rb",
"#{@tapioca_path}/generators/**/*.rb", # TODO: Here for backcompat, remove later
"#{@tapioca_path}/compilers/**/*.rb",
]).each do |compiler|
require File.expand_path(compiler)
end

say("Done", :green)
end

sig { void }
def load_application
say("Loading Rails application... ")

load_rails_application(
environment_load: true,
eager_load: @eager_load
)

say("Done", :green)
end

sig { void }
def abort_if_pending_migrations!
return unless File.exist?("config/application.rb")
return unless defined?(::Rake)

Rails.application.load_tasks
if Rake::Task.task_defined?("db:abort_if_pending_migrations")
Rake::Task["db:abort_if_pending_migrations"].invoke
end
end
end
end
end
Loading