From 0d9dcec6dda4c4ecbaa54553dd5c483ab4695143 Mon Sep 17 00:00:00 2001 From: Andy Waite <13400+andyw8@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:54:52 -0400 Subject: [PATCH] Assume UTF-8 when detecting Rails --- lib/ruby_lsp/setup_bundler.rb | 2 +- sorbet/rbi/shims/encoding.rbi | 7 ++++ sorbet/rbi/shims/pathname.rbi | 16 +++++++++ test/fixtures/rails_application.rb | 1 + test/setup_bundler_test.rb | 57 ++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 sorbet/rbi/shims/encoding.rbi create mode 100644 sorbet/rbi/shims/pathname.rbi diff --git a/lib/ruby_lsp/setup_bundler.rb b/lib/ruby_lsp/setup_bundler.rb index b8a5eacc56..ca10ea7ced 100644 --- a/lib/ruby_lsp/setup_bundler.rb +++ b/lib/ruby_lsp/setup_bundler.rb @@ -286,7 +286,7 @@ def correct_relative_remote_paths sig { returns(T::Boolean) } def rails_app? config = Pathname.new("config/application.rb").expand_path - application_contents = config.read if config.exist? + application_contents = config.read(external_encoding: Encoding::UTF_8) if config.exist? return false unless application_contents /class .* < (::)?Rails::Application/.match?(application_contents) diff --git a/sorbet/rbi/shims/encoding.rbi b/sorbet/rbi/shims/encoding.rbi new file mode 100644 index 0000000000..bb9c80b2d6 --- /dev/null +++ b/sorbet/rbi/shims/encoding.rbi @@ -0,0 +1,7 @@ +# typed: true + +class Encoding < Object + sig {returns(Encoding)} + sig {returns(String)} + def self.default_external; end +end diff --git a/sorbet/rbi/shims/pathname.rbi b/sorbet/rbi/shims/pathname.rbi new file mode 100644 index 0000000000..774bc090be --- /dev/null +++ b/sorbet/rbi/shims/pathname.rbi @@ -0,0 +1,16 @@ +# typed: false + +class Pathname + sig do + params( + external_encoding: T.any(String, Encoding), + internal_encoding: T.any(String, Encoding), + encoding: T.any(String, Encoding), + textmode: BasicObject, + binmode: BasicObject, + autoclose: BasicObject, + mode: String, + ).returns(String) + end + def read(external_encoding: T.unsafe(nil), internal_encoding: T.unsafe(nil), encoding: T.unsafe(nil), textmode: T.unsafe(nil), binmode: T.unsafe(nil), autoclose: T.unsafe(nil), mode: T.unsafe(nil)); end +end diff --git a/test/fixtures/rails_application.rb b/test/fixtures/rails_application.rb index 27eff561a4..cb43f7bf47 100644 --- a/test/fixtures/rails_application.rb +++ b/test/fixtures/rails_application.rb @@ -1,4 +1,5 @@ module MyApp class Application < Rails::Application + # あ end end diff --git a/test/setup_bundler_test.rb b/test/setup_bundler_test.rb index afe3d39104..c360a23856 100644 --- a/test/setup_bundler_test.rb +++ b/test/setup_bundler_test.rb @@ -506,6 +506,39 @@ def test_ruby_lsp_rails_is_automatically_included_in_rails_apps end end + def test_ruby_lsp_rails_detection_handles_lang_from_environment + with_default_external_encoding("us-ascii") do + Dir.mktmpdir do |dir| + FileUtils.mkdir("#{dir}/config") + FileUtils.cp("test/fixtures/rails_application.rb", "#{dir}/config/application.rb") + Dir.chdir(dir) do + File.write(File.join(dir, "Gemfile"), <<~GEMFILE) + source "https://rubygems.org" + gem "rails" + GEMFILE + + capture_subprocess_io do + Bundler.with_unbundled_env do + # Run bundle install to generate the lockfile + system("bundle install") + end + end + + Object.any_instance.expects(:system).with( + bundle_env(dir, ".ruby-lsp/Gemfile"), + "(bundle check || bundle install) 1>&2", + ).returns(true) + Bundler.with_unbundled_env do + run_script(dir) + end + + assert_path_exists(".ruby-lsp/Gemfile") + assert_match('gem "ruby-lsp-rails"', File.read(".ruby-lsp/Gemfile")) + end + end + end + end + def test_recovers_from_stale_lockfiles Dir.mktmpdir do |dir| custom_dir = File.join(dir, ".ruby-lsp") @@ -575,6 +608,30 @@ def test_recovers_from_stale_lockfiles private + def with_default_external_encoding(encoding, &block) + ignore_warnings do + original_encoding = Encoding.default_external + begin + Encoding.default_external = encoding + block.call + ensure + Encoding.default_external = original_encoding + end + end + end + + def ignore_warnings(&block) + # Since overwriting the encoding emits a warning + previous = $VERBOSE + $VERBOSE = nil + + begin + block.call + ensure + $VERBOSE = previous + end + end + # This method runs the script and then immediately unloads it. This allows us to make assertions against the effects # of running the script multiple times def run_script(path = Dir.pwd, expected_path: nil, **options)