Skip to content

Commit

Permalink
Check generated RBI files correctness with Sorbet
Browse files Browse the repository at this point in the history
Signed-off-by: Alexandre Terrasa <alexandre.terrasa@shopify.com>
  • Loading branch information
Morriar committed Mar 4, 2022
1 parent 9ef7521 commit 05ec3dc
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 12 deletions.
9 changes: 7 additions & 2 deletions lib/tapioca/commands/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,13 @@ def execute

if @auto_strictness
say("")
update_gem_rbis_strictnesses([], gem_dir: @gem_dir, dsl_dir: @outpath.to_s)
say("")
validate_rbi_files(
command: default_command(:dsl, @requested_constants.join(" ")),
gem_dir: @gem_dir,
dsl_dir: @outpath.to_s,
auto_strictness: @auto_strictness,
compilers: Runtime::Reflection.descendants_of(Tapioca::Dsl::Compiler)
)
end

say("All operations performed in working directory.", [:green, :bold])
Expand Down
17 changes: 14 additions & 3 deletions lib/tapioca/commands/gem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,13 @@ def execute
end

if anything_done
gem_names = gem_queue.map(&:name)
update_gem_rbis_strictnesses(gem_names, gem_dir: @outpath.to_s, dsl_dir: @dsl_dir) if @auto_strictness
validate_rbi_files(
command: default_command(:gem, @gem_names.join(" ")),
gem_dir: @outpath.to_s,
dsl_dir: @dsl_dir,
auto_strictness: @auto_strictness,
gems: bundle.dependencies
)

say("All operations performed in working directory.", [:green, :bold])
say("Please review changes and commit them.", [:green, :bold])
Expand All @@ -104,7 +109,13 @@ def sync(should_verify: false)
].any?

if anything_done
update_gem_rbis_strictnesses([], gem_dir: @outpath.to_s, dsl_dir: @dsl_dir) if @auto_strictness
validate_rbi_files(
command: default_command(:gem),
gem_dir: @outpath.to_s,
dsl_dir: @dsl_dir,
auto_strictness: @auto_strictness,
gems: bundle.dependencies
)

say("All operations performed in working directory.", [:green, :bold])
say("Please review changes and commit them.", [:green, :bold])
Expand Down
71 changes: 64 additions & 7 deletions lib/tapioca/helpers/rbi_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,24 @@ module RBIHelper
requires_ancestor { Thor::Shell }
requires_ancestor { SorbetHelper }

sig { params(gem_names: T::Array[String], gem_dir: String, dsl_dir: String).void }
def update_gem_rbis_strictnesses(gem_names, gem_dir: DEFAULT_GEM_DIR, dsl_dir: DEFAULT_DSL_DIR)
return unless File.directory?(dsl_dir)

sig do
params(
command: String,
gem_dir: String,
dsl_dir: String,
auto_strictness: T::Boolean,
gems: T::Array[Gemfile::GemSpec],
compilers: T::Array[Class]
).void
end
def validate_rbi_files(command:, gem_dir:, dsl_dir:, auto_strictness:, gems: [], compilers: [])
error_url_base = Spoom::Sorbet::Errors::DEFAULT_ERROR_URL_BASE

say("Typechecking RBI files... ")
say("Checking generated RBI files... ")
res = sorbet(
"--no-config",
"--error-url-base=#{error_url_base}",
"--isolate-error-code 4010",
"--stop-after namer",
dsl_dir,
gem_dir
)
Expand All @@ -28,10 +35,60 @@ def update_gem_rbis_strictnesses(gem_names, gem_dir: DEFAULT_GEM_DIR, dsl_dir: D
errors = Spoom::Sorbet::Errors::Parser.parse_string(res.err)

if errors.empty?
say("No error found", [:green, :bold])
say(" No error found\n\n", [:green, :bold])
return
end

parse_errors = errors.select { |error| error.code < 4000 }

if parse_errors.any?
say_error(<<~ERR, :red)
##### INTERNAL ERROR #####
There are parse errors in the generated RBI files.
This seems related to a bug in Tapioca.
Please open an issue at https://github.com/Shopify/tapioca/issues/new with the following information:
Tapioca v#{Tapioca::VERSION}
Command:
#{command}
ERR

say_error(<<~ERR, :red) if gems.any?
Gems:
#{gems.map { |gem| " #{gem.name} (#{gem.version})" }.join("\n")}
ERR

say_error(<<~ERR, :red) if compilers.any?
Compilers:
#{compilers.map { |compiler| " #{compiler.name}" }.join("\n")}
ERR

say_error(<<~ERR, :red)
Errors:
#{parse_errors.map { |error| " #{error}" }.join("\n")}
##########################
ERR
end

redef_errors = errors.select { |error| error.code == 4010 }
update_gem_rbis_strictnesses(redef_errors, gems.map(&:name), gem_dir) if auto_strictness

Kernel.exit(1) if parse_errors.any?
end

private

sig { params(errors: T::Array[Spoom::Sorbet::Errors::Error], gem_names: T::Array[String], gem_dir: String).void }
def update_gem_rbis_strictnesses(errors, gem_names, gem_dir)
files = []

errors.each do |error|
Expand Down

0 comments on commit 05ec3dc

Please sign in to comment.