From 95ed300a4fceceaf4b0b95baef7701a1e0bc30aa Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 13 Jan 2026 05:08:14 -0500 Subject: [PATCH 01/21] Avoid rbs pollution (#1146) We were using the sig/shims directory for some internally helpful shims; unfortunately that exported them during gem installs, causing https://github.com/castwide/solargraph/issues/1144 --- {sig => rbs}/shims/ast/0/node.rbs | 0 {sig => rbs}/shims/ast/2.4/.rbs_meta.yaml | 0 {sig => rbs}/shims/ast/2.4/ast.rbs | 0 {sig => rbs}/shims/parser/3.2.0.1/builders/default.rbs | 0 {sig => rbs}/shims/parser/3.2.0.1/manifest.yaml | 0 {sig => rbs}/shims/parser/3.2.0.1/parser.rbs | 0 {sig => rbs}/shims/parser/3.2.0.1/polyfill.rbs | 0 {sig => rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml | 0 {sig => rbs}/shims/thor/1.2.0.1/manifest.yaml | 0 {sig => rbs}/shims/thor/1.2.0.1/thor.rbs | 0 rbs_collection.yaml | 2 +- 11 files changed, 1 insertion(+), 1 deletion(-) rename {sig => rbs}/shims/ast/0/node.rbs (100%) rename {sig => rbs}/shims/ast/2.4/.rbs_meta.yaml (100%) rename {sig => rbs}/shims/ast/2.4/ast.rbs (100%) rename {sig => rbs}/shims/parser/3.2.0.1/builders/default.rbs (100%) rename {sig => rbs}/shims/parser/3.2.0.1/manifest.yaml (100%) rename {sig => rbs}/shims/parser/3.2.0.1/parser.rbs (100%) rename {sig => rbs}/shims/parser/3.2.0.1/polyfill.rbs (100%) rename {sig => rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml (100%) rename {sig => rbs}/shims/thor/1.2.0.1/manifest.yaml (100%) rename {sig => rbs}/shims/thor/1.2.0.1/thor.rbs (100%) diff --git a/sig/shims/ast/0/node.rbs b/rbs/shims/ast/0/node.rbs similarity index 100% rename from sig/shims/ast/0/node.rbs rename to rbs/shims/ast/0/node.rbs diff --git a/sig/shims/ast/2.4/.rbs_meta.yaml b/rbs/shims/ast/2.4/.rbs_meta.yaml similarity index 100% rename from sig/shims/ast/2.4/.rbs_meta.yaml rename to rbs/shims/ast/2.4/.rbs_meta.yaml diff --git a/sig/shims/ast/2.4/ast.rbs b/rbs/shims/ast/2.4/ast.rbs similarity index 100% rename from sig/shims/ast/2.4/ast.rbs rename to rbs/shims/ast/2.4/ast.rbs diff --git a/sig/shims/parser/3.2.0.1/builders/default.rbs b/rbs/shims/parser/3.2.0.1/builders/default.rbs similarity index 100% rename from sig/shims/parser/3.2.0.1/builders/default.rbs rename to rbs/shims/parser/3.2.0.1/builders/default.rbs diff --git a/sig/shims/parser/3.2.0.1/manifest.yaml b/rbs/shims/parser/3.2.0.1/manifest.yaml similarity index 100% rename from sig/shims/parser/3.2.0.1/manifest.yaml rename to rbs/shims/parser/3.2.0.1/manifest.yaml diff --git a/sig/shims/parser/3.2.0.1/parser.rbs b/rbs/shims/parser/3.2.0.1/parser.rbs similarity index 100% rename from sig/shims/parser/3.2.0.1/parser.rbs rename to rbs/shims/parser/3.2.0.1/parser.rbs diff --git a/sig/shims/parser/3.2.0.1/polyfill.rbs b/rbs/shims/parser/3.2.0.1/polyfill.rbs similarity index 100% rename from sig/shims/parser/3.2.0.1/polyfill.rbs rename to rbs/shims/parser/3.2.0.1/polyfill.rbs diff --git a/sig/shims/thor/1.2.0.1/.rbs_meta.yaml b/rbs/shims/thor/1.2.0.1/.rbs_meta.yaml similarity index 100% rename from sig/shims/thor/1.2.0.1/.rbs_meta.yaml rename to rbs/shims/thor/1.2.0.1/.rbs_meta.yaml diff --git a/sig/shims/thor/1.2.0.1/manifest.yaml b/rbs/shims/thor/1.2.0.1/manifest.yaml similarity index 100% rename from sig/shims/thor/1.2.0.1/manifest.yaml rename to rbs/shims/thor/1.2.0.1/manifest.yaml diff --git a/sig/shims/thor/1.2.0.1/thor.rbs b/rbs/shims/thor/1.2.0.1/thor.rbs similarity index 100% rename from sig/shims/thor/1.2.0.1/thor.rbs rename to rbs/shims/thor/1.2.0.1/thor.rbs diff --git a/rbs_collection.yaml b/rbs_collection.yaml index 898239cac..d94e1c896 100644 --- a/rbs_collection.yaml +++ b/rbs_collection.yaml @@ -2,7 +2,7 @@ sources: - type: local name: shims - path: sig/shims + path: rbs/shims - type: git name: ruby/gem_rbs_collection From ce12a5f63cba2e72b04453c756751a3fafb2d0a0 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 13 Jan 2026 05:11:44 -0500 Subject: [PATCH 02/21] Fix 'solargraph pin --references ClassName' private method call (#1150) --- lib/solargraph/api_map.rb | 12 ++++++------ spec/shell_spec.rb | 32 +++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index cc3031ea5..6c0da316e 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -711,6 +711,12 @@ def inner_get_methods_from_reference(fq_reference_tag, namespace_pin, type, scop methods end + # @param fq_sub_tag [String] + # @return [String, nil] + def qualify_superclass fq_sub_tag + store.qualify_superclass fq_sub_tag + end + private # A hash of source maps with filename keys. @@ -804,12 +810,6 @@ def path_macros @path_macros ||= {} end - # @param fq_sub_tag [String] - # @return [String, nil] - def qualify_superclass fq_sub_tag - store.qualify_superclass fq_sub_tag - end - # Get the namespace's type (Class or Module). # # @param fqns [String] A fully qualified namespace diff --git a/spec/shell_spec.rb b/spec/shell_spec.rb index b9dc6b327..3b8dc0426 100644 --- a/spec/shell_spec.rb +++ b/spec/shell_spec.rb @@ -57,7 +57,37 @@ def bundle_exec(*cmd) end end - describe 'pin' do + describe 'pin on a class' do + let(:api_map) { instance_double(Solargraph::ApiMap) } + let(:string_pin) { instance_double(Solargraph::Pin::Namespace, name: 'String') } + + before do + allow(Solargraph::ApiMap).to receive(:load_with_cache).and_return(api_map) + allow(Solargraph::Pin::Namespace).to receive(:===).with(string_pin).and_return(true) + allow(string_pin).to receive(:return_type).and_return(Solargraph::ComplexType.parse('String')) + allow(api_map).to receive(:get_path_pins).with('String').and_return([string_pin]) + end + + context 'with --references option' do + let(:object_pin) { instance_double(Solargraph::Pin::Namespace, name: 'Object') } + + before do + allow(Solargraph::Pin::Namespace).to receive(:===).with(object_pin).and_return(true) + allow(api_map).to receive(:qualify_superclass).with('String').and_return('Object') + allow(api_map).to receive(:get_path_pins).with('Object').and_return([object_pin]) + end + + it 'prints a pin with info' do + out = capture_both do + shell.options = { references: true } + shell.pin('String') + end + expect(out).to include('# Superclass:') + end + end + end + + describe 'pin on a method' do let(:api_map) { instance_double(Solargraph::ApiMap) } let(:to_s_pin) { instance_double(Solargraph::Pin::Method, return_type: Solargraph::ComplexType.parse('String')) } From 5ae55584e399822af0a12b386229acffdd9bd7bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lek=C3=AB=20Mula?= Date: Wed, 14 Jan 2026 01:47:12 +0100 Subject: [PATCH 03/21] Improve memory efficiency of Position class (#1054) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use each_line instead of text.lines Avoid allocating additional strings, instead use sliced substrings * gitignore vendor/cache * Remove redundant end_with? Co-authored-by: Jean Boussier * Remove benchamrks https://github.com/castwide/solargraph/pull/1054#discussion_r2312388042 * String#index(offset:) FTW 🚀 https://github.com/castwide/solargraph/pull/1054#issuecomment-3240029936 Co-authored-by: Jean Boussier * fix rubocop --------- Co-authored-by: Jean Boussier --- .gitignore | 1 + lib/solargraph/position.rb | 32 +++++++++++++++++++++----------- spec/position_spec.rb | 16 ++++++++++++++++ 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 2819165b1..75510d96b 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ coverage /Makefile /.pryrc /.rspec-local +vendor/cache diff --git a/lib/solargraph/position.rb b/lib/solargraph/position.rb index 74606f142..e47ed8bc8 100644 --- a/lib/solargraph/position.rb +++ b/lib/solargraph/position.rb @@ -58,8 +58,22 @@ def inspect # @return [Integer] def self.to_offset text, position return 0 if text.empty? - # @sg-ignore Unresolved call to + on Integer - text.lines[0...position.line].sum(&:length) + position.character + newline_index = -1 + cursor = 0 + line = -1 + + last_line_index = 0 + while (newline_index = text.index("\n", newline_index + 1)) && line <= position.line + line += 1 + break if line == position.line + line_length = newline_index - last_line_index + + cursor += line_length.zero? ? 1 : line_length + + last_line_index = newline_index + end + + cursor + position.character end # Get a numeric offset for the specified text and a position identified @@ -81,16 +95,12 @@ def self.line_char_to_offset text, line, character def self.from_offset text, offset cursor = 0 line = 0 - character = nil - text.lines.each do |l| - line_length = l.length - char_length = l.chomp.length - if cursor + char_length >= offset - character = offset - cursor - break - end - cursor += line_length + character = offset + newline_index = -1 + + while (newline_index = text.index("\n", newline_index + 1)) && newline_index < offset line += 1 + character = offset - newline_index - 1 end character = 0 if character.nil? and (cursor - offset).between?(0, 1) raise InvalidOffsetError if character.nil? diff --git a/spec/position_spec.rb b/spec/position_spec.rb index fa30cf7d9..88dedcd26 100644 --- a/spec/position_spec.rb +++ b/spec/position_spec.rb @@ -12,6 +12,22 @@ expect(orig).to be(norm) end + it 'finds offset from position' do + text = "\n class Foo\n def bar baz, boo = 'boo'\n end\n end\n " + expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(0, 0))).to eq(0) + expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(0, 4))).to eq(4) + expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(2, 12))).to eq(29) + expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(2, 27))).to eq(44) + end + + it 'constructs position from offset' do + text = "\n class Foo\n def bar baz, boo = 'boo'\n end\n end\n " + expect(Solargraph::Position.from_offset(text, 0)).to eq(Solargraph::Position.new(0, 0)) + expect(Solargraph::Position.from_offset(text, 4)).to eq(Solargraph::Position.new(1, 3)) + expect(Solargraph::Position.from_offset(text, 29)).to eq(Solargraph::Position.new(2, 12)) + expect(Solargraph::Position.from_offset(text, 44)).to eq(Solargraph::Position.new(2, 27)) + end + it "raises an error for objects that cannot be normalized" do expect { Solargraph::Position.normalize('0, 1') From 4c05f2806078c3433b08ce3703eeb8a34e9325fc Mon Sep 17 00:00:00 2001 From: Fred Snyder Date: Wed, 14 Jan 2026 03:15:31 -0500 Subject: [PATCH 04/21] Raise InvalidOffsetError for offsets > text (#1155) * Raise InvalidOffsetError for offsets > text * Linting * Fix fencepost error * Additional fencepost test * Document exception --- lib/solargraph/position.rb | 15 +++++++++------ spec/position_spec.rb | 13 +++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/solargraph/position.rb b/lib/solargraph/position.rb index e47ed8bc8..a0d7bbc2e 100644 --- a/lib/solargraph/position.rb +++ b/lib/solargraph/position.rb @@ -58,22 +58,21 @@ def inspect # @return [Integer] def self.to_offset text, position return 0 if text.empty? + newline_index = -1 - cursor = 0 line = -1 - last_line_index = 0 + while (newline_index = text.index("\n", newline_index + 1)) && line <= position.line line += 1 break if line == position.line - line_length = newline_index - last_line_index - - cursor += line_length.zero? ? 1 : line_length + line_length = newline_index - last_line_index last_line_index = newline_index end - cursor + position.character + last_line_index += 1 if position.line > 0 + last_line_index + position.character end # Get a numeric offset for the specified text and a position identified @@ -89,10 +88,14 @@ def self.line_char_to_offset text, line, character # Get a position for the specified text and offset. # + # @raise [InvalidOffsetError] if the offset is outside the text range + # # @param text [String] # @param offset [Integer] # @return [Position] def self.from_offset text, offset + raise InvalidOffsetError if offset > text.length + cursor = 0 line = 0 character = offset diff --git a/spec/position_spec.rb b/spec/position_spec.rb index 88dedcd26..e8dab1960 100644 --- a/spec/position_spec.rb +++ b/spec/position_spec.rb @@ -18,6 +18,7 @@ expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(0, 4))).to eq(4) expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(2, 12))).to eq(29) expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(2, 27))).to eq(44) + expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(3, 8))).to eq(58) end it 'constructs position from offset' do @@ -33,4 +34,16 @@ Solargraph::Position.normalize('0, 1') }.to raise_error(ArgumentError) end + + it 'avoids fencepost errors' do + text = " class Foo\n def bar baz, boo = 'boo'\n end\n end\n " + offset = Solargraph::Position.to_offset(text, Solargraph::Position.new(3, 6)) + expect(offset).to eq(67) + end + + it 'avoids fencepost errors with multiple blank lines' do + text = " class Foo\n def bar baz, boo = 'boo'\n\n end\n end\n " + offset = Solargraph::Position.to_offset(text, Solargraph::Position.new(4, 6)) + expect(offset).to eq(68) + end end From 29fbd34ba5e61f14577455be1fdb60332c880171 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 15 Jan 2026 09:49:06 -0500 Subject: [PATCH 05/21] Spec performance fixes On my machine, I got a 33% speed-up with these tweaks: before: Finished in 1 minute 15.88 seconds after: Finished in 49 seconds --- lib/solargraph/diagnostics/base.rb | 3 ++- lib/solargraph/diagnostics/type_check.rb | 4 ++-- spec/api_map_method_spec.rb | 3 +-- .../message/extended/check_gem_version_spec.rb | 17 ++++++++++------- spec/language_server/protocol_spec.rb | 4 ++++ spec/pin/base_spec.rb | 6 ++++-- spec/yard_map/mapper_spec.rb | 11 ----------- 7 files changed, 23 insertions(+), 25 deletions(-) diff --git a/lib/solargraph/diagnostics/base.rb b/lib/solargraph/diagnostics/base.rb index ff91a9062..31b9a4342 100644 --- a/lib/solargraph/diagnostics/base.rb +++ b/lib/solargraph/diagnostics/base.rb @@ -20,8 +20,9 @@ def initialize *args # # @param source [Solargraph::Source] # @param api_map [Solargraph::ApiMap] + # @param workspace [Solargraph::Workspace, nil] # @return [Array] - def diagnose source, api_map + def diagnose source, api_map, workspace: nil [] end end diff --git a/lib/solargraph/diagnostics/type_check.rb b/lib/solargraph/diagnostics/type_check.rb index 80f53eb7c..78de3d490 100644 --- a/lib/solargraph/diagnostics/type_check.rb +++ b/lib/solargraph/diagnostics/type_check.rb @@ -7,11 +7,11 @@ module Diagnostics # class TypeCheck < Base # @return [Array] - def diagnose source, api_map + def diagnose source, api_map, workspace: nil # return [] unless args.include?('always') || api_map.workspaced?(source.filename) severity = Diagnostics::Severities::ERROR level = (args.reverse.find { |a| ['normal', 'typed', 'strict', 'strong'].include?(a) }) || :normal - checker = Solargraph::TypeChecker.new(source.filename, api_map: api_map, level: level.to_sym) + checker = Solargraph::TypeChecker.new(source.filename, api_map: api_map, level: level.to_sym, workspace: workspace) checker.problems .sort { |a, b| a.location.range.start.line <=> b.location.range.start.line } .map do |problem| diff --git a/spec/api_map_method_spec.rb b/spec/api_map_method_spec.rb index 9d4e4f553..ae3bab875 100644 --- a/spec/api_map_method_spec.rb +++ b/spec/api_map_method_spec.rb @@ -111,8 +111,7 @@ class B end describe '#get_method_stack' do - let(:out) { StringIO.new } - let(:api_map) { Solargraph::ApiMap.load_with_cache(Dir.pwd, out) } + let(:api_map) { Solargraph::ApiMap.load('') } context 'with stdlib that has vital dependencies' do let(:external_requires) { ['yaml'] } diff --git a/spec/language_server/message/extended/check_gem_version_spec.rb b/spec/language_server/message/extended/check_gem_version_spec.rb index 935917442..783770ddf 100644 --- a/spec/language_server/message/extended/check_gem_version_spec.rb +++ b/spec/language_server/message/extended/check_gem_version_spec.rb @@ -33,6 +33,10 @@ end it "responds to update actions" do + status = instance_double(Process::Status) + allow(status).to receive(:==).with(0).and_return(true) + allow(Open3).to receive(:capture2).with('gem update solargraph').and_return(['', status]) + host = Solargraph::LanguageServer::Host.new message = Solargraph::LanguageServer::Message::Extended::CheckGemVersion.new(host, {}, current: Gem::Version.new('0.0.1')) message.process @@ -42,13 +46,12 @@ response = data end reader.receive host.flush - expect { - action = { - "id" => response['id'], - "result" => response['params']['actions'].first - } - host.receive action - }.not_to raise_error + action = { + "id" => response['id'], + "result" => response['params']['actions'].first + } + host.receive action + expect(Open3).to have_received(:capture2).with('gem update solargraph') end it 'uses bundler' do diff --git a/spec/language_server/protocol_spec.rb b/spec/language_server/protocol_spec.rb index e88fb9c05..fdaf69e73 100644 --- a/spec/language_server/protocol_spec.rb +++ b/spec/language_server/protocol_spec.rb @@ -432,9 +432,13 @@ def bar baz end it "handles $/solargraph/documentGems" do + status = instance_double(Process::Status) + allow(status).to receive(:==).with(0).and_return(true) + allow(Open3).to receive(:capture2).with('solargraph', 'gems').and_return(['', status]) @protocol.request '$/solargraph/documentGems', {} response = @protocol.response expect(response['error']).to be_nil + expect(Open3).to have_received(:capture2).with('solargraph', 'gems') end it "handles textDocument/formatting" do diff --git a/spec/pin/base_spec.rb b/spec/pin/base_spec.rb index 1a6cfd1e8..06f558162 100644 --- a/spec/pin/base_spec.rb +++ b/spec/pin/base_spec.rb @@ -50,8 +50,10 @@ end it 'deals well with known closure combination issue' do - Solargraph::Shell.new.uncache('yard') - api_map = Solargraph::ApiMap.load_with_cache('.', $stderr) + # if this fails you might not have an rbs collection installed + api_map = Solargraph::ApiMap.load '' + bench = Solargraph::Bench.new(external_requires: ['yard']) + api_map.catalog bench pins = api_map.get_method_stack('YARD::Docstring', 'parser', scope: :class) expect(pins.length).to eq(1) parser_method_pin = pins.first diff --git a/spec/yard_map/mapper_spec.rb b/spec/yard_map/mapper_spec.rb index d45af985b..88704471b 100644 --- a/spec/yard_map/mapper_spec.rb +++ b/spec/yard_map/mapper_spec.rb @@ -32,17 +32,6 @@ expect(pins.map(&:return_type).uniq.map(&:to_s)).to eq(['self']) end - it 'marks correct return type from RuboCop::Options.new' do - # Using rubocop because it's a known dependency - rubocop = Gem::Specification.find_by_name('rubocop') - Solargraph::Yardoc.cache([], rubocop) - Solargraph::Yardoc.load!(rubocop) - pins = Solargraph::YardMap::Mapper.new(YARD::Registry.all).map - pins = pins.select { |pin| pin.path == 'RuboCop::Options.new' } - expect(pins.map(&:return_type).uniq.map(&:to_s)).to eq(['self']) - expect(pins.flat_map(&:signatures).map(&:return_type).uniq.map(&:to_s)).to eq(['self']) - end - it 'marks non-explicit methods' do # Using rspec-expectations because it's a known dependency rspec = Gem::Specification.find_by_name('rspec-expectations') From 70ea4bb19c23cd5b204a4b62eaa7aa916b34eee1 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 15 Jan 2026 21:33:12 -0500 Subject: [PATCH 06/21] Add rbs collection in undercover run --- .github/workflows/rspec.yml | 13 ++++++++++--- spec/api_map_method_spec.rb | 1 + spec/library_spec.rb | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index c82ade49b..e21f06694 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -58,8 +58,6 @@ jobs: run: | bundle _2.5.23_ install bundle update rbs # use latest available for this Ruby version - bundle list - bundle exec solargraph pin 'Bundler::Dsl#source' - name: Update types run: | bundle exec rbs collection update @@ -77,9 +75,18 @@ jobs: uses: ruby/setup-ruby@v1 with: ruby-version: '3.4' + # match version in Gemfile.lock and use same version below + bundler: 2.5.23 bundler-cache: false + - name: Set rbs version + run: echo "gem 'rbs', '${{ matrix.rbs-version }}'" >> .Gemfile - name: Install gems - run: bundle install + run: | + bundle _2.5.23__ install + bundle update rbs # use latest available for this Ruby version + - name: Update types + run: | + bundle exec rbs collection update - name: Run tests run: bundle exec rake spec - name: Check PR coverage diff --git a/spec/api_map_method_spec.rb b/spec/api_map_method_spec.rb index ae3bab875..435a4e290 100644 --- a/spec/api_map_method_spec.rb +++ b/spec/api_map_method_spec.rb @@ -127,6 +127,7 @@ class B let(:method_stack) { api_map.get_method_stack('Thor', 'desc', scope: :class) } it 'handles finding Thor.desc' do + # if this fails you may not have an rbs collection installed expect(method_stack).not_to be_empty end end diff --git a/spec/library_spec.rb b/spec/library_spec.rb index 34de9e1f0..95c4a2366 100644 --- a/spec/library_spec.rb +++ b/spec/library_spec.rb @@ -32,7 +32,7 @@ end it "returns a Completion" do - library = Solargraph::Library.new(Solargraph::Workspace.new(Dir.pwd, + library = Solargraph::Library.new(Solargraph::Workspace.new('', Solargraph::Workspace::Config.new)) library.attach Solargraph::Source.load_string(%( require 'backport' From 8c049fb77f57544be7dbd74835a49aeff9fdc526 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 15 Jan 2026 21:35:17 -0500 Subject: [PATCH 07/21] Add rbs collection in undercover run --- .github/workflows/rspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index e21f06694..ea3585988 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -82,7 +82,7 @@ jobs: run: echo "gem 'rbs', '${{ matrix.rbs-version }}'" >> .Gemfile - name: Install gems run: | - bundle _2.5.23__ install + bundle _2.5.23_ install bundle update rbs # use latest available for this Ruby version - name: Update types run: | From e428f804885e01f2548a2cd70963d6a3b2ac373e Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 15 Jan 2026 21:42:34 -0500 Subject: [PATCH 08/21] Fix copy-and-paste-o --- .github/workflows/rspec.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index ea3585988..13f1c79b5 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -78,8 +78,6 @@ jobs: # match version in Gemfile.lock and use same version below bundler: 2.5.23 bundler-cache: false - - name: Set rbs version - run: echo "gem 'rbs', '${{ matrix.rbs-version }}'" >> .Gemfile - name: Install gems run: | bundle _2.5.23_ install From ffc25d6d08fdf488086295ad72b769a5fc401b49 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 15 Jan 2026 21:58:38 -0500 Subject: [PATCH 09/21] Perform specific caching --- spec/api_map_method_spec.rb | 6 ++++++ spec/pin/base_spec.rb | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/spec/api_map_method_spec.rb b/spec/api_map_method_spec.rb index 435a4e290..944dcaf64 100644 --- a/spec/api_map_method_spec.rb +++ b/spec/api_map_method_spec.rb @@ -118,6 +118,9 @@ class B let(:method_stack) { api_map.get_method_stack('YAML', 'safe_load', scope: :class) } it 'handles the YAML gem aliased to Psych' do + spec = Gem::Specification.find_by_name('yaml') + api_map.cache_gem(spec) + expect(method_stack).not_to be_empty end end @@ -127,6 +130,9 @@ class B let(:method_stack) { api_map.get_method_stack('Thor', 'desc', scope: :class) } it 'handles finding Thor.desc' do + spec = Gem::Specification.find_by_name('thor') + api_map.cache_gem(spec) + # if this fails you may not have an rbs collection installed expect(method_stack).not_to be_empty end diff --git a/spec/pin/base_spec.rb b/spec/pin/base_spec.rb index 06f558162..296b1e349 100644 --- a/spec/pin/base_spec.rb +++ b/spec/pin/base_spec.rb @@ -52,6 +52,10 @@ it 'deals well with known closure combination issue' do # if this fails you might not have an rbs collection installed api_map = Solargraph::ApiMap.load '' + + spec = Gem::Specification.find_by_name('yard') + api_map.cache_gem(spec) + bench = Solargraph::Bench.new(external_requires: ['yard']) api_map.catalog bench pins = api_map.get_method_stack('YARD::Docstring', 'parser', scope: :class) From f9319c6a55120630a19e1ebfbb012b14707491a3 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 16 Jan 2026 19:39:01 -0500 Subject: [PATCH 10/21] Pre-release branch 2026-01-12 (#1152) * Fix merge * Adjust annotations * Fix typecheck errors * Fix merge * Fix merge * Fix some @sg-ignores * Fix merge * Merge branch 'intersection_types' into flow_sensitive_typing_2_0 * Fix RuboCop issue * Fix type issues * Fix type issues * Fix rspec.yml * Fix rspec.yml * Add @sg-ignores * Remove @sg-ignores * Merge branch 'or_support_in_flow_sensitive_typing' into union_type_enforcement * Fix spec * Fix annotations * Fix RuboCop issues * Bump RBS versions in rspec test * Fix version * Fix version matrix * Fix version matrix * Fix version matrix * Fix version matrix * Fix version matrix * Exclude another * Exclude another * Add version, fix doc * init -> config * Fix rbs-version for Ruby 4.0 in CI workflow * Clean up ruby-version entries in rspec.yml Removed deprecated ruby-version entries for RBS. * Fix RBS version for Ruby 4.0 in workflow * Fix merge * Improve signature combination Use our generated RBS signature from parameters as a key to combine method signatures from RBS/YARD pins. This is closer to what RBS does than the current technique of using the arity alone, and fixes a key degenerate case in Integer#+ revealed by updated definitions used by recently released RBS gems * Update annotations * Drop annotation * Fix RuboCop issue * Fix merge * Don't use solargraph-rspec branch * Fix merge * Debug * Add another use of stdlib dependencies in RBS * Mock additional call * Fix annotations * Update types in rspec undercover * Debug * Debug * Drop incorrect rbs collection use in spec * Update rubocop todo * Revert change * Fix RuboCop issue * Fix annotations * Fix annotations * RuboCop fix * Use "type arity" to guide signature combination * Update rubocop todo * Include return type arity in comparison * Add dodgy return type * Fix RuboCop issue * Add Ruby 4.0 jobs * Exclude another combo * Exclude another combo * Update rules to use report? * Fix merge * Fix merge * Drop dead code * Bump version to 0.59.0.dev.1 * Rename rule * Update RuboCop todo file * Update RuboCop todo file * Ratchet rubocop TODO file * Move to skip: * Mark spec as pending * Revert spec change * Drop old workaround * Fix merge * Fix typechecking issues * Revert doc * Fix spelling * Fix merge issue * Exclude the current gemspec from pins brought in from gem * Check pathname instead * Add sg-ignore * Avoid rbs pollution We were using the sig/shims directory for some internally helpful shims; unfortunately that exported them during gem installs, causing https://github.com/castwide/solargraph/issues/1144 * Test with RBS 4.0.0.dev.5 * Open up in gemspec * Fix missing spot * Typecheck using RBS prereleases * Move point of ignoring cached gems for gem projects * Fix issues resolving cgi escape functions * Be more careful marking things as stdlib * Reclassify rbs gem * Fix merge * Add sg-ignore * Fix merge * Remove outdated workaround * Fix @sg-ignore name * Restore workaround * Restore workaround * Merge branch 'flow_sensitive_typing_2_0' into 2025-01-06 * Fix method signature * Fix annotations * Add regression test and fix for issue found during future merge * Add regression test and fix for issue found during future merge * Fix merge * Fix merge * Fix merge * Fix merge * Use correct field for self type resolution Add a regression test and fix for self type resolution issue found on a future branch * Fix 'solargraph pin --references ClassName' private method call * Add error handling * Fix another location with another test case * Drop now-unneeded @sg-ignore * Don't log caching for each dependent library This causes duplicate logging on standard libraries, many of which are esoteric (e.g., "cgi-escaping"). The current method as of the 2025-01-06 branch would result in each stdlib library being cached individually. * Drop logging entirely * Fix some types based on future branch feedback * Provide Gem::Specification to outside interface * Provide Gem::Specification to outside interface * Use #to_spec * Provide Gem::Specification to outside interface * Fix typechecking error * Use consistent bundler versions * Fix type issue * Fix annotations based on future branch feedback * Add some @todos * Fix annotations * Fix annotations * Fix annotation * Add diff::lcs shim * Improve spec expectations * Add @sg-ignore * Fix rspec checks to run on all types of PRs * Fix merge * Fix merge * Fix merge --- lib/solargraph/api_map.rb | 7 +++++++ spec/api_map_method_spec.rb | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 904edff8e..e580687e7 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -760,6 +760,13 @@ def qualify_superclass fq_sub_tag store.qualify_superclass fq_sub_tag end + # @param require_path [String] + # + # @return [Array, nil] + def resolve_require require_path + workspace.resolve_require require_path + end + private # A hash of source maps with filename keys. diff --git a/spec/api_map_method_spec.rb b/spec/api_map_method_spec.rb index ceae4fcf8..7cbec546a 100644 --- a/spec/api_map_method_spec.rb +++ b/spec/api_map_method_spec.rb @@ -125,8 +125,8 @@ class B let(:method_stack) { api_map.get_method_stack('YAML', 'safe_load', scope: :class) } it 'handles the YAML gem aliased to Psych' do - spec = Gem::Specification.find_by_name('yaml') - api_map.cache_gem(spec) + specs = api_map.resolve_require('yaml') + specs.each { |spec| api_map.cache_gem(spec) } expect(method_stack).not_to be_empty end @@ -137,8 +137,8 @@ class B let(:method_stack) { api_map.get_method_stack('Thor', 'desc', scope: :class) } it 'handles finding Thor.desc' do - spec = Gem::Specification.find_by_name('thor') - api_map.cache_gem(spec) + specs = api_map.resolve_require('thor') + specs.each { |spec| api_map.cache_gem(spec) } # if this fails you may not have an rbs collection installed expect(method_stack).not_to be_empty From 861a899384a6b5a718bf3648d106d308496debfd Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 27 Jan 2026 21:19:50 -0500 Subject: [PATCH 11/21] Ensure api_map catalogs new pins --- spec/api_map_method_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/api_map_method_spec.rb b/spec/api_map_method_spec.rb index 7cbec546a..40b83efb3 100644 --- a/spec/api_map_method_spec.rb +++ b/spec/api_map_method_spec.rb @@ -127,6 +127,7 @@ class B it 'handles the YAML gem aliased to Psych' do specs = api_map.resolve_require('yaml') specs.each { |spec| api_map.cache_gem(spec) } + api_map.catalog bench expect(method_stack).not_to be_empty end @@ -139,6 +140,7 @@ class B it 'handles finding Thor.desc' do specs = api_map.resolve_require('thor') specs.each { |spec| api_map.cache_gem(spec) } + api_map.catalog bench # if this fails you may not have an rbs collection installed expect(method_stack).not_to be_empty From 9216d730a5c7a223611181aa570f974b714dace8 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 27 Jan 2026 21:29:38 -0500 Subject: [PATCH 12/21] Avoid cache_doc_map_gems if possible --- spec/doc_map_spec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/doc_map_spec.rb b/spec/doc_map_spec.rb index 7c541da27..0ac440c55 100644 --- a/spec/doc_map_spec.rb +++ b/spec/doc_map_spec.rb @@ -124,7 +124,9 @@ context 'with require as bundle/require' do it 'imports all gems when bundler/require used' do doc_map_with_bundler_require = described_class.new(['bundler/require'], workspace, out: nil) - doc_map_with_bundler_require.cache_doc_map_gems!(nil) + if doc_map_with_bundler_require.pins.length <= plain_doc_map.pins.length + doc_map_with_bundler_require.cache_doc_map_gems!(nil) + end expect(doc_map_with_bundler_require.pins.length - plain_doc_map.pins.length).to be_positive end end From 7741fcaf4a0f84506feffe7cf79e86bfe17d4d40 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 27 Jan 2026 21:48:36 -0500 Subject: [PATCH 13/21] Avoid load_with_cache if possible --- spec/pin/method_spec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/pin/method_spec.rb b/spec/pin/method_spec.rb index c2ef40448..c4d33b0d0 100644 --- a/spec/pin/method_spec.rb +++ b/spec/pin/method_spec.rb @@ -554,7 +554,9 @@ class Foo # on type. Let's make sure we combine those with anything else # found (e.g., additions from the BigDecimal RBS collection) # without collapsing signatures - api_map = Solargraph::ApiMap.load_with_cache(Dir.pwd, nil) + api_map = Solargraph::ApiMap.load(Dir.pwd) + bench = Solargraph::Bench.new external_requires: ['bigdecimal'] + api_map.catalog(bench) method = api_map.get_method_stack('Integer', '+', scope: :instance).first expect(method.signatures.count).to be > 3 end From 80e0c94a41ccf8c4ab826c730e1220273ae91bda Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 27 Jan 2026 21:59:13 -0500 Subject: [PATCH 14/21] Avoid load_with_cache if possible --- spec/rbs_map/conversions_spec.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/spec/rbs_map/conversions_spec.rb b/spec/rbs_map/conversions_spec.rb index 61771ac10..d9a0aea7a 100644 --- a/spec/rbs_map/conversions_spec.rb +++ b/spec/rbs_map/conversions_spec.rb @@ -95,7 +95,12 @@ def bar: () -> untyped context 'with standard loads for solargraph project' do before :all do # rubocop:disable RSpec/BeforeAfterAll - @api_map = Solargraph::ApiMap.load_with_cache('.') + @api_map = Solargraph::ApiMap.load('.') + gems = ['parser', 'ast', 'open3'] + bench = Solargraph::Bench.new(workspace: @api_map.workspace, external_requires: gems) + @api_map.catalog(bench) + @api_map.cache_all_for_doc_map! + @api_map.catalog(bench) end let(:api_map) { @api_map } @@ -149,7 +154,9 @@ class Sub < Hash[Symbol, untyped] if Gem::Version.new(RBS::VERSION) >= Gem::Version.new('3.9.1') context 'with method pin for Open3.capture2e' do it 'accepts chdir kwarg' do - api_map = Solargraph::ApiMap.load_with_cache('.', $stdout) + api_map = Solargraph::ApiMap.load('.') + bench = Solargraph::Bench.new(external_requires: ['open3']) + api_map.catalog(bench) method_pin = api_map.pins.find do |pin| pin.is_a?(Solargraph::Pin::Method) && pin.path == 'Open3.capture2e' From c0596adce9f3d98fdb96c2127b0e0b52031db053 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 27 Jan 2026 22:15:24 -0500 Subject: [PATCH 15/21] Use library with fewer dependencies to cache --- spec/yard_map/mapper_spec.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/spec/yard_map/mapper_spec.rb b/spec/yard_map/mapper_spec.rb index fb8378161..26ee93fbe 100644 --- a/spec/yard_map/mapper_spec.rb +++ b/spec/yard_map/mapper_spec.rb @@ -4,8 +4,8 @@ end def pins_with require - doc_map = Solargraph::DocMap.new([require], @api_map.workspace, out: nil) - doc_map.cache_doc_map_gems!(nil) + doc_map = Solargraph::DocMap.new([require], @api_map.workspace, out: $stderr) + doc_map.cache_doc_map_gems!($stderr) doc_map.pins end @@ -37,9 +37,10 @@ def pins_with require it 'marks correct return type from RuboCop::Options.new' do # Using rubocop because it's a known dependency - pins = pins_with('rubocop').select { |pin| pin.path == 'RuboCop::Options.new' } - expect(pins.map(&:return_type).uniq.map(&:to_s)).to eq(['self']) - expect(pins.flat_map(&:signatures).map(&:return_type).uniq.map(&:to_s)).to eq(['self']) + all_pins = pins_with('open3') + pins = all_pins.select { |pin| pin.path == 'Open3.capture2e' } + expect(pins.map(&:return_type).uniq.map(&:to_s)).to eq(['Array(String, Process::Status)']) + expect(pins.flat_map(&:signatures).map(&:return_type).uniq.map(&:to_s)).to eq(['Array(String, Process::Status)']) end it 'marks non-explicit methods' do From 55612e78b643d36385cf2d94632808f7f4807808 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 27 Jan 2026 22:26:43 -0500 Subject: [PATCH 16/21] Simulate yardoc run --- spec/yardoc_spec.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/spec/yardoc_spec.rb b/spec/yardoc_spec.rb index 6cd575de0..80e8d4764 100644 --- a/spec/yardoc_spec.rb +++ b/spec/yardoc_spec.rb @@ -62,9 +62,18 @@ end it 'is idempotent' do + result = instance_double(Process::Status) + allow(result).to receive(:success?).and_return(true) + allow(Open3).to receive(:capture2e).and_return([output, result]).once do + # write the complete file to simulate successful run + FileUtils.mkdir_p(gem_yardoc_path) + FileUtils.touch(File.join(gem_yardoc_path, 'complete')) + end + described_class.build_docs(gem_yardoc_path, [], gemspec) described_class.build_docs(gem_yardoc_path, [], gemspec) # second time - expect(File.exist?(File.join(gem_yardoc_path, 'complete'))).to be true + + expect(Open3).to have_received(:capture2e).once end context 'with an error from yard' do From c5d5843fb4e7ea826d3ade6d641b4c5875d5cde5 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 27 Jan 2026 22:27:32 -0500 Subject: [PATCH 17/21] Add bundle cache --- .github/workflows/rspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 5b7e991f9..bd9cba48d 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -74,7 +74,7 @@ jobs: # # match version in Gemfile.lock and use same version below bundler: 2.5.23 - bundler-cache: false + bundler-cache: true - name: Set rbs version run: echo "gem 'rbs', '${{ matrix.rbs-version }}'" >> .Gemfile # /home/runner/.rubies/ruby-head/lib/ruby/gems/3.5.0+2/gems/rbs-3.9.4/lib/rbs.rb:11: From 9d725f3bbce08b37e14b372ef0c92258144005f6 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 27 Jan 2026 22:52:23 -0500 Subject: [PATCH 18/21] Add empty lines --- spec/language_server/protocol_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/language_server/protocol_spec.rb b/spec/language_server/protocol_spec.rb index fdaf69e73..1b42935b9 100644 --- a/spec/language_server/protocol_spec.rb +++ b/spec/language_server/protocol_spec.rb @@ -435,8 +435,10 @@ def bar baz status = instance_double(Process::Status) allow(status).to receive(:==).with(0).and_return(true) allow(Open3).to receive(:capture2).with('solargraph', 'gems').and_return(['', status]) + @protocol.request '$/solargraph/documentGems', {} response = @protocol.response + expect(response['error']).to be_nil expect(Open3).to have_received(:capture2).with('solargraph', 'gems') end From a6df0bf554476fc7196223b699ce33a299c09ac3 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 27 Jan 2026 23:02:42 -0500 Subject: [PATCH 19/21] Cache bundles --- .github/workflows/plugins.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index 4556215f1..9835cebdb 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -57,7 +57,7 @@ jobs: ruby-version: 3.4 # keep same as typecheck.yml # See https://github.com/castwide/solargraph/actions/runs/19000135777/job/54265647107?pr=1119 rubygems: latest - bundler-cache: false + bundler-cache: true - uses: awalsh128/cache-apt-pkgs-action@latest with: packages: yq @@ -86,7 +86,7 @@ jobs: uses: ruby/setup-ruby@v1 with: ruby-version: 3.4 # keep same as typecheck.yml - bundler-cache: false + bundler-cache: true - uses: awalsh128/cache-apt-pkgs-action@latest with: packages: yq @@ -126,7 +126,7 @@ jobs: with: ruby-version: 3.4 rubygems: latest - bundler-cache: false + bundler-cache: true - name: Install gems run: | set -x @@ -181,7 +181,7 @@ jobs: with: # solargraph-rails supports Ruby 3.0+ ruby-version: '3.0' - bundler-cache: false + bundler-cache: true # https://github.com/apiology/solargraph/actions/runs/19400815835/job/55508092473?pr=17 rubygems: latest bundler: latest From f4ad280cd734ee3fc4cfe4b1ebd780da3c075f61 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 27 Jan 2026 23:15:29 -0500 Subject: [PATCH 20/21] Split up regression cases --- .github/workflows/plugins.yml | 86 +++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index 9835cebdb..015d262a9 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -15,7 +15,7 @@ permissions: contents: read jobs: - regression: + rails_and_rspec_typechecking: runs-on: ubuntu-latest steps: @@ -44,9 +44,36 @@ jobs: run: bundle exec rbs collection update - name: Ensure typechecking still works run: bundle exec solargraph typecheck --level strong + rails_and_rspec_specs: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.4 # keep same as typecheck.yml + bundler-cache: true + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: yq + version: 1.0 + - name: Install gems + run: | + echo 'gem "solargraph-rails"' > .Gemfile + echo 'gem "solargraph-rspec"' >> .Gemfile + bundle install + bundle update --pre rbs + - name: Configure to use plugins + run: | + bundle exec solargraph config + yq -yi '.plugins += ["solargraph-rails"]' .solargraph.yml + yq -yi '.plugins += ["solargraph-rspec"]' .solargraph.yml + - name: Install gem types + run: bundle exec rbs collection update - name: Ensure specs still run run: bundle exec rake spec - rails: + rails_typechecking: runs-on: ubuntu-latest steps: @@ -75,9 +102,36 @@ jobs: run: bundle exec rbs collection update - name: Ensure typechecking still works run: bundle exec solargraph typecheck --level strong + rails_specs: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.4 # keep same as typecheck.yml + # See https://github.com/castwide/solargraph/actions/runs/19000135777/job/54265647107?pr=1119 + rubygems: latest + bundler-cache: true + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: yq + version: 1.0 + - name: Install gems + run: | + echo 'gem "solargraph-rails"' > .Gemfile + bundle install + bundle update --pre rbs + - name: Configure to use plugins + run: | + bundle exec solargraph config + yq -yi '.plugins += ["solargraph-rails"]' .solargraph.yml + - name: Install gem types + run: bundle exec rbs collection update - name: Ensure specs still run run: bundle exec rake spec - rspec: + rspec_typechecking: runs-on: ubuntu-latest steps: @@ -104,9 +158,33 @@ jobs: run: bundle exec rbs collection update - name: Ensure typechecking still works run: bundle exec solargraph typecheck --level strong + rspec_specs: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.4 # keep same as typecheck.yml + bundler-cache: true + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: yq + version: 1.0 + - name: Install gems + run: | + echo 'gem "solargraph-rspec"' >> .Gemfile + bundle install + bundle update --pre rbs + - name: Configure to use plugins + run: | + bundle exec solargraph config + yq -yi '.plugins += ["solargraph-rspec"]' .solargraph.yml + - name: Install gem types + run: bundle exec rbs collection update - name: Ensure specs still run run: bundle exec rake spec - run_solargraph_rspec_specs: # check out solargraph-rspec as well as this project, and point the former to use the latter as a local gem runs-on: ubuntu-latest From 8db11598bc2d16785d61d3180d9b0c36c8fbbb0c Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 1 Mar 2026 20:23:40 -0500 Subject: [PATCH 21/21] Try revert --- .github/workflows/rspec.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index ba368b173..4762f9905 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -71,6 +71,10 @@ jobs: with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true + # see https://github.com/castwide/solargraph/actions/runs/19391419903/job/55485410493?pr=1119 + # + # match version in Gemfile.lock and use same version below + bundler: 2.5.23 - name: Set rbs version run: echo "gem 'rbs', '${{ matrix.rbs-version }}'" >> .Gemfile # /home/runner/.rubies/ruby-head/lib/ruby/gems/3.5.0+2/gems/rbs-3.9.4/lib/rbs.rb:11: