diff --git a/exe/ruby-lsp b/exe/ruby-lsp index 3a44d07556..a9292cf07f 100755 --- a/exe/ruby-lsp +++ b/exe/ruby-lsp @@ -37,6 +37,10 @@ parser = OptionParser.new do |opts| options[:launcher] = true end + opts.on("--beta", "Use pre-release server gems") do + options[:beta] = true + end + opts.on("-h", "--help", "Print this help") do puts opts.help puts @@ -66,6 +70,7 @@ if ENV["BUNDLE_GEMFILE"].nil? if options[:launcher] flags = [] flags << "--debug" if options[:debug] + flags << "--beta" if options[:beta] exit exec(Gem.ruby, File.expand_path("ruby-lsp-launcher", __dir__), *flags) end diff --git a/exe/ruby-lsp-launcher b/exe/ruby-lsp-launcher index d7600061fd..3bb4df7917 100755 --- a/exe/ruby-lsp-launcher +++ b/exe/ruby-lsp-launcher @@ -49,16 +49,18 @@ pid = if Gem.win_platform? ["-I", File.expand_path(path)] end - Process.spawn( + args = [ Gem.ruby, *load_path, File.expand_path("../lib/ruby_lsp/scripts/compose_bundle_windows.rb", __dir__), raw_initialize, - ) + ] + args << "--beta" if ARGV.include?("--beta") + Process.spawn(*args) else fork do require_relative "../lib/ruby_lsp/scripts/compose_bundle" - compose(raw_initialize) + compose(raw_initialize, beta: ARGV.include?("--beta")) end end diff --git a/lib/ruby_lsp/scripts/compose_bundle.rb b/lib/ruby_lsp/scripts/compose_bundle.rb index 626e5ea68a..56d2f6bfdb 100644 --- a/lib/ruby_lsp/scripts/compose_bundle.rb +++ b/lib/ruby_lsp/scripts/compose_bundle.rb @@ -1,7 +1,7 @@ # typed: true # frozen_string_literal: true -def compose(raw_initialize) +def compose(raw_initialize, beta: false) require_relative "../setup_bundler" require "json" require "uri" @@ -12,7 +12,7 @@ def compose(raw_initialize) workspace_path = workspace_uri && URI(workspace_uri).to_standardized_path workspace_path ||= Dir.pwd - env = RubyLsp::SetupBundler.new(workspace_path, launcher: true).setup! + env = RubyLsp::SetupBundler.new(workspace_path, launcher: true, beta: beta).setup! File.open(File.join(".ruby-lsp", "bundle_env"), "w") do |f| f.flock(File::LOCK_EX) diff --git a/lib/ruby_lsp/scripts/compose_bundle_windows.rb b/lib/ruby_lsp/scripts/compose_bundle_windows.rb index 3bdc94115a..7770b7a973 100644 --- a/lib/ruby_lsp/scripts/compose_bundle_windows.rb +++ b/lib/ruby_lsp/scripts/compose_bundle_windows.rb @@ -5,4 +5,4 @@ # When this is invoked on Windows, we pass the raw initialize as an argument to this script. On other platforms, we # invoke the compose method from inside a forked process -compose(ARGV.first) +compose(ARGV.first, beta: ARGV.include?("--beta")) diff --git a/lib/ruby_lsp/setup_bundler.rb b/lib/ruby_lsp/setup_bundler.rb index 661a672a92..6a2ad51e05 100644 --- a/lib/ruby_lsp/setup_bundler.rb +++ b/lib/ruby_lsp/setup_bundler.rb @@ -40,6 +40,7 @@ def initialize(project_path, **options) @project_path = project_path @branch = options[:branch] #: String? @launcher = options[:launcher] #: bool? + @beta = options[:beta] #: bool? force_output_to_stderr! if @launcher # Regular bundle paths @@ -170,6 +171,7 @@ def write_custom_gemfile unless @dependencies["ruby-lsp"] ruby_lsp_entry = +'gem "ruby-lsp", require: false, group: :development' + ruby_lsp_entry << ", \">= 0.a\"" if @beta ruby_lsp_entry << ", github: \"Shopify/ruby-lsp\", branch: \"#{@branch}\"" if @branch parts << ruby_lsp_entry end diff --git a/test/setup_bundler_test.rb b/test/setup_bundler_test.rb index 26cf355905..c4327c62e8 100644 --- a/test/setup_bundler_test.rb +++ b/test/setup_bundler_test.rb @@ -1067,6 +1067,82 @@ def test_is_resilient_to_pipe_being_closed_by_client_during_compose end end + def test_beta_adds_prerelease_constraint_to_composed_gemfile + in_temp_dir do |dir| + File.write(File.join(dir, "Gemfile"), <<~GEMFILE) + source "https://rubygems.org" + gem "rdoc" + GEMFILE + + capture_subprocess_io do + Bundler.with_unbundled_env do + system("bundle install") + run_script(dir, beta: true) + end + end + + gemfile_content = File.read(File.join(dir, ".ruby-lsp", "Gemfile")) + assert_match(/gem "ruby-lsp", require: false, group: :development, ">= 0.a"/, gemfile_content) + end + end + + def test_beta_adds_prerelease_constraint_to_composed_gemfile_in_launcher_mode + in_temp_dir do |dir| + File.write(File.join(dir, "Gemfile"), <<~GEMFILE) + source "https://rubygems.org" + gem "rdoc" + GEMFILE + + capture_subprocess_io do + Bundler.with_unbundled_env do + system("bundle install") + RubyLsp::SetupBundler.new(dir, launcher: true, beta: true).setup! + end + end + + gemfile_content = File.read(File.join(dir, ".ruby-lsp", "Gemfile")) + assert_match(/gem "ruby-lsp", require: false, group: :development, ">= 0.a"/, gemfile_content) + end + end + + def test_beta_has_no_effect_when_ruby_lsp_is_in_the_bundle_in_launcher_mode + in_temp_dir do |dir| + File.write(File.join(dir, "Gemfile"), <<~GEMFILE) + source "https://rubygems.org" + gem "ruby-lsp" + GEMFILE + + capture_subprocess_io do + Bundler.with_unbundled_env do + system("bundle install") + RubyLsp::SetupBundler.new(dir, launcher: true, beta: true).setup! + end + end + + gemfile_content = File.read(File.join(dir, ".ruby-lsp", "Gemfile")) + refute_match(/gem "ruby-lsp", require: false, group: :development, ">= 0.a"/, gemfile_content) + end + end + + def test_beta_has_no_effect_when_ruby_lsp_is_in_the_bundle + in_temp_dir do |dir| + File.write(File.join(dir, "Gemfile"), <<~GEMFILE) + source "https://rubygems.org" + gem "ruby-lsp" + GEMFILE + + capture_subprocess_io do + Bundler.with_unbundled_env do + system("bundle install") + run_script(dir, beta: true) + end + end + + gemfile_content = File.read(File.join(dir, ".ruby-lsp", "Gemfile")) + refute_match(/gem "ruby-lsp", require: false, group: :development, ">= 0.a"/, gemfile_content) + end + end + private def in_temp_dir(&block)