From 19dc932b729940af4c674ebc9fcd86591aac9b42 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Tue, 1 Mar 2022 11:08:27 -0500 Subject: [PATCH 1/3] Rename `RBIHelper` -> `SignaturesHelper` Signed-off-by: Alexandre Terrasa --- lib/tapioca/gem/listeners/sorbet_signatures.rb | 2 +- lib/tapioca/gem/pipeline.rb | 2 +- lib/tapioca/helpers/{rbi_helper.rb => signatures_helper.rb} | 2 +- lib/tapioca/internal.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename lib/tapioca/helpers/{rbi_helper.rb => signatures_helper.rb} (93%) diff --git a/lib/tapioca/gem/listeners/sorbet_signatures.rb b/lib/tapioca/gem/listeners/sorbet_signatures.rb index d02e2eb79..9eed97db3 100644 --- a/lib/tapioca/gem/listeners/sorbet_signatures.rb +++ b/lib/tapioca/gem/listeners/sorbet_signatures.rb @@ -8,7 +8,7 @@ class SorbetSignatures < Base extend T::Sig include Runtime::Reflection - include RBIHelper + include SignaturesHelper TYPE_PARAMETER_MATCHER = /T\.type_parameter\(:?([[:word:]]+)\)/ diff --git a/lib/tapioca/gem/pipeline.rb b/lib/tapioca/gem/pipeline.rb index d48c03f8e..591a7827e 100644 --- a/lib/tapioca/gem/pipeline.rb +++ b/lib/tapioca/gem/pipeline.rb @@ -8,7 +8,7 @@ module Gem class Pipeline extend T::Sig include Runtime::Reflection - include RBIHelper + include SignaturesHelper IGNORED_SYMBOLS = T.let(["YAML", "MiniTest", "Mutex"], T::Array[String]) diff --git a/lib/tapioca/helpers/rbi_helper.rb b/lib/tapioca/helpers/signatures_helper.rb similarity index 93% rename from lib/tapioca/helpers/rbi_helper.rb rename to lib/tapioca/helpers/signatures_helper.rb index 98be6dd14..41eccc236 100644 --- a/lib/tapioca/helpers/rbi_helper.rb +++ b/lib/tapioca/helpers/signatures_helper.rb @@ -2,7 +2,7 @@ # frozen_string_literal: true module Tapioca - module RBIHelper + module SignaturesHelper extend T::Sig sig { params(sig_string: String).returns(String) } diff --git a/lib/tapioca/internal.rb b/lib/tapioca/internal.rb index de264f3ec..4450b7db5 100644 --- a/lib/tapioca/internal.rb +++ b/lib/tapioca/internal.rb @@ -11,7 +11,7 @@ require "tapioca/runtime/generic_type_registry" require "tapioca/helpers/cli_helper" require "tapioca/helpers/config_helper" -require "tapioca/helpers/rbi_helper" +require "tapioca/helpers/signatures_helper" require "tapioca/helpers/shims_helper" require "tapioca/helpers/sorbet_helper" require "tapioca/commands" From 2ab2cb3780a2554415c4c4054419e23f43c709e2 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Tue, 1 Mar 2022 11:18:08 -0500 Subject: [PATCH 2/3] Extract `update_strictnesses` into `RBIHelper` Signed-off-by: Alexandre Terrasa --- lib/tapioca/commands/gem.rb | 60 ++-------------------------- lib/tapioca/helpers/rbi_helper.rb | 66 +++++++++++++++++++++++++++++++ lib/tapioca/internal.rb | 1 + 3 files changed, 71 insertions(+), 56 deletions(-) create mode 100644 lib/tapioca/helpers/rbi_helper.rb diff --git a/lib/tapioca/commands/gem.rb b/lib/tapioca/commands/gem.rb index e5cb4af4a..f22a84411 100644 --- a/lib/tapioca/commands/gem.rb +++ b/lib/tapioca/commands/gem.rb @@ -5,6 +5,7 @@ module Tapioca module Commands class Gem < Command include SorbetHelper + include RBIHelper sig do params( @@ -78,7 +79,8 @@ def execute end if anything_done - update_strictnesses(gem_queue.map(&:name), gem_dir: @outpath.to_s, dsl_dir: @dsl_dir) if @auto_strictness + gem_names = gem_queue.map(&:name) + update_gem_rbis_strictnesses(gem_names, gem_dir: @outpath.to_s, dsl_dir: @dsl_dir) if @auto_strictness say("All operations performed in working directory.", [:green, :bold]) say("Please review changes and commit them.", [:green, :bold]) @@ -102,7 +104,7 @@ def sync(should_verify: false) ].any? if anything_done - update_strictnesses([], gem_dir: @outpath.to_s, dsl_dir: @dsl_dir) if @auto_strictness + update_gem_rbis_strictnesses([], gem_dir: @outpath.to_s, dsl_dir: @dsl_dir) if @auto_strictness say("All operations performed in working directory.", [:green, :bold]) say("Please review changes and commit them.", [:green, :bold]) @@ -379,60 +381,6 @@ def merge_with_exported_rbi(gem, file) say_error("\n\n RBIs exported by `#{gem.name}` contain errors and can't be used:", :yellow) say_error("Cause: #{e.message} (#{e.location})") end - - sig { params(gem_names: T::Array[String], gem_dir: String, dsl_dir: String).void } - def update_strictnesses(gem_names, gem_dir: DEFAULT_GEM_DIR, dsl_dir: DEFAULT_DSL_DIR) - return unless File.directory?(dsl_dir) - - error_url_base = Spoom::Sorbet::Errors::DEFAULT_ERROR_URL_BASE - - say("Typechecking RBI files... ") - res = sorbet( - "--no-config", - "--error-url-base=#{error_url_base}", - "--isolate-error-code 4010", - dsl_dir, - gem_dir - ) - say(" Done", :green) - - errors = Spoom::Sorbet::Errors::Parser.parse_string(res.err) - - if errors.empty? - say("No error found", [:green, :bold]) - return - end - - files = [] - - errors.each do |error| - # Collect the file with error - files << error.file - error.more.each do |line| - # Also collect the conflicting definition file paths - next unless line.include?("Previous definition") - files << line.split(":").first&.strip - end - end - - files - .uniq - .sort - .select do |file| - name = gem_name_from_rbi_path(file) - file.start_with?(gem_dir) && (gem_names.empty? || gem_names.include?(name)) - end.each do |file| - Spoom::Sorbet::Sigils.change_sigil_in_file(file, "false") - say("\n Changed strictness of #{file} to `typed: false` (conflicting with DSL files)", [:yellow, :bold]) - end - - say("\n") - end - - sig { params(path: String).returns(String) } - def gem_name_from_rbi_path(path) - T.must(File.basename(path, ".rbi").split("@").first) - end end end end diff --git a/lib/tapioca/helpers/rbi_helper.rb b/lib/tapioca/helpers/rbi_helper.rb new file mode 100644 index 000000000..c4c1478c1 --- /dev/null +++ b/lib/tapioca/helpers/rbi_helper.rb @@ -0,0 +1,66 @@ +# typed: strict +# frozen_string_literal: true + +module Tapioca + module RBIHelper + extend T::Sig + extend T::Helpers + + 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) + + error_url_base = Spoom::Sorbet::Errors::DEFAULT_ERROR_URL_BASE + + say("Typechecking RBI files... ") + res = sorbet( + "--no-config", + "--error-url-base=#{error_url_base}", + "--isolate-error-code 4010", + dsl_dir, + gem_dir + ) + say(" Done", :green) + + errors = Spoom::Sorbet::Errors::Parser.parse_string(res.err) + + if errors.empty? + say("No error found", [:green, :bold]) + return + end + + files = [] + + errors.each do |error| + # Collect the file with error + files << error.file + error.more.each do |line| + # Also collect the conflicting definition file paths + next unless line.include?("Previous definition") + files << line.split(":").first&.strip + end + end + + files + .uniq + .sort + .select do |file| + name = gem_name_from_rbi_path(file) + file.start_with?(gem_dir) && (gem_names.empty? || gem_names.include?(name)) + end.each do |file| + Spoom::Sorbet::Sigils.change_sigil_in_file(file, "false") + say("\n Changed strictness of #{file} to `typed: false` (conflicting with DSL files)", [:yellow, :bold]) + end + + say("\n") + end + + sig { params(path: String).returns(String) } + def gem_name_from_rbi_path(path) + T.must(File.basename(path, ".rbi").split("@").first) + end + end +end diff --git a/lib/tapioca/internal.rb b/lib/tapioca/internal.rb index 4450b7db5..9e93aa247 100644 --- a/lib/tapioca/internal.rb +++ b/lib/tapioca/internal.rb @@ -12,6 +12,7 @@ require "tapioca/helpers/cli_helper" require "tapioca/helpers/config_helper" require "tapioca/helpers/signatures_helper" +require "tapioca/helpers/rbi_helper" require "tapioca/helpers/shims_helper" require "tapioca/helpers/sorbet_helper" require "tapioca/commands" From 820f7b7a8696b7d8fc62517753c0ce3d570f7c72 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Tue, 1 Mar 2022 11:52:25 -0500 Subject: [PATCH 3/3] Auto-update gem RBI strictnesses after DSL generation Signed-off-by: Alexandre Terrasa --- lib/tapioca/commands/dsl.rb | 16 +++++- spec/tapioca/cli/dsl_spec.rb | 99 ++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/lib/tapioca/commands/dsl.rb b/lib/tapioca/commands/dsl.rb index 114c9a63c..e0bafa813 100644 --- a/lib/tapioca/commands/dsl.rb +++ b/lib/tapioca/commands/dsl.rb @@ -4,6 +4,9 @@ module Tapioca module Commands class Dsl < Command + include SorbetHelper + include RBIHelper + sig do params( requested_constants: T::Array[String], @@ -17,6 +20,8 @@ class Dsl < Command quiet: T::Boolean, verbose: T::Boolean, number_of_workers: T.nilable(Integer), + auto_strictness: T::Boolean, + gem_dir: String, rbi_formatter: RBIFormatter ).void end @@ -32,6 +37,8 @@ def initialize( quiet: false, verbose: false, number_of_workers: nil, + auto_strictness: true, + gem_dir: DEFAULT_GEM_DIR, rbi_formatter: DEFAULT_RBI_FORMATTER ) @requested_constants = requested_constants @@ -45,6 +52,8 @@ def initialize( @quiet = quiet @verbose = verbose @number_of_workers = number_of_workers + @auto_strictness = auto_strictness + @gem_dir = gem_dir @rbi_formatter = rbi_formatter super() @@ -102,9 +111,14 @@ def execute perform_dsl_verification(outpath) else purge_stale_dsl_rbi_files(rbi_files_to_purge) - say("Done", :green) + if @auto_strictness + say("") + update_gem_rbis_strictnesses([], gem_dir: @gem_dir, dsl_dir: @outpath.to_s) + say("") + end + say("All operations performed in working directory.", [:green, :bold]) say("Please review changes and commit them.", [:green, :bold]) end diff --git a/spec/tapioca/cli/dsl_spec.rb b/spec/tapioca/cli/dsl_spec.rb index 9926d3a4e..116621472 100644 --- a/spec/tapioca/cli/dsl_spec.rb +++ b/spec/tapioca/cli/dsl_spec.rb @@ -93,6 +93,10 @@ class Post create sorbet/rbi/dsl/post.rbi Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -202,6 +206,10 @@ class Comment create sorbet/rbi/dsl/post.rbi Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -281,6 +289,10 @@ class Role create sorbet/rbi/dsl/foo/role.rbi Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -344,6 +356,10 @@ class Comment create rbis/post.rbi Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -392,6 +408,10 @@ class Comment create sorbet/rbi/dsl/post.rbi Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -423,6 +443,10 @@ class Post Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -492,6 +516,10 @@ class Post remove sorbet/rbi/dsl/to_be_deleted/foo.rbi Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -603,6 +631,10 @@ class User; end remove sorbet/rbi/dsl/user.rbi Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -681,6 +713,10 @@ def self.gather_constants create sorbet/rbi/dsl/post.rbi Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -769,6 +805,10 @@ def self.gather_constants create sorbet/rbi/dsl/job.rbi Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -872,6 +912,10 @@ def self.gather_constants create sorbet/rbi/dsl/post.rbi Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -983,6 +1027,10 @@ class Image force sorbet/rbi/dsl/image.rbi Done + + Typechecking RBI files... Done + No error found + All operations performed in working directory. Please review changes and commit them. OUT @@ -1180,6 +1228,57 @@ class Post refute_success_status(result) end end + + describe "strictness" do + it "must turn the strictness of gem RBI files with errors to false" do + @project.require_real_gem("smart_properties", "1.15.0") + @project.bundle_install + + @project.write("sorbet/rbi/gems/foo@0.0.1.rbi", <<~RBI) + # typed: true + + module Post::SmartPropertiesGeneratedMethods + def foo; end + end + RBI + + @project.write("sorbet/rbi/gems/bar@1.0.0.rbi", <<~RBI) + # typed: true + + module Post::SmartPropertiesGeneratedMethods + sig { params(title: T.nilable(::String), subtitle: T.nilable(::String)).returns(T.nilable(::String)) } + def title=(title, subtitle); end + end + RBI + + @project.write("lib/post.rb", <<~RB) + require "smart_properties" + + class Post + include SmartProperties + property :title, accepts: String + end + RB + + result = @project.tapioca("dsl Post") + + assert_includes(result.out, <<~OUT) + Typechecking RBI files... Done + + Changed strictness of sorbet/rbi/gems/bar@1.0.0.rbi to `typed: false` (conflicting with DSL files) + OUT + + assert_file_strictness("true", "sorbet/rbi/gems/foo@0.0.1.rbi") + assert_file_strictness("false", "sorbet/rbi/gems/bar@1.0.0.rbi") + assert_file_strictness("true", "sorbet/rbi/dsl/post.rbi") + + assert_empty_stderr(result) + assert_success_status(result) + + @project.remove("sorbet/rbi/gems") + @project.remove("sorbet/rbi/dsl") + end + end end end end