Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support configuring custom rspec command in VS Code #57

Merged
merged 7 commits into from
Feb 3, 2025

Conversation

westonkd
Copy link
Contributor

@westonkd westonkd commented Jan 6, 2025

ruby-lsp already does a good job of inferring the base rspec command to run based on the presence of a Gemfile or binstup.

This pull request allows further customization of the rspec command using the addonSettings VS Code configuration exposed by ruby-lsp

Check out the modifications to README.md for descriptions of the two newly-added configuration options (rspecCommand and useRelativePaths).

These two new options can be used in conjunction to solve issues like those described in #27 (using ruby-lsp-rspec with docker):

.vscode/settings.json

{
  "rubyLsp.addonSettings": {
    "Ruby LSP RSpec": {
      "rspecCommand": "docker compose exec app rspec",
      "useRelativePaths": true
    }
  }
}

@westonkd westonkd mentioned this pull request Jan 6, 2025
@carlqt
Copy link

carlqt commented Jan 7, 2025

I was just thinking of contributing this same feature. Thanks!

Hope this get merges soon 🙏

@westonkd
Copy link
Contributor Author

@st0012 Any thoughts on this feature or implementation? Thanks!

@westonkd
Copy link
Contributor Author

I just hit another use case where the combination of the two settings I added here are not quite sufficient to get things working (Docker + a monorepo-style setup).

When I get time I'll push a change making the settings interface slightly more flexible than what I've added here.

@st0012
Copy link
Owner

st0012 commented Jan 25, 2025

Hi sorry for the delay. I understand the need of custom RSpec commands, but what's the problem useRelativePaths is going to solve?

From my experience, if the test files need to be run with a relative path, it usually indicates that the project should properly utilize VS Code's multi-root workspaces feature.

westonkd and others added 2 commits January 25, 2025 16:15
This commit adds an option (consumed from VS Code settings) that
allows a debug mode to troubleshoot configuration issues.

Further, this commit clarifies the preferred approach for using
this addon with Dev Containers.

Projects that use Docker or other container technologies for development
should use a the VS Code Dev Containers extension to run Ruby LSP _within_
the dev Container.

This prevents situations where the spec paths provided to rspec are
host machine paths rather than container paths.
@westonkd
Copy link
Contributor Author

👋 Hey! No problem for the delay, thanks for taking a look.

but what's the problem useRelativePaths is going to solve?
I was working in a development environment that:

  • Used Docker containers to run the application in development
  • Ran rspec within those same containers
  • Ran VS Code extensions (like Ruby LSP) on the host machine, not within the container

With that setup, the spec file path was an absolute path pointing to the file on the host machine, not the path within the container.

One way to fix that was to add support for a relative path so the spec path was correct, even if it was generated on the host machine but used in a container.

I've thought more about that and don't think it's the right solution. Instead, using a Dev Container and running Ruby LSP extension in that container yields the correct spec paths without the need for an additional setting.

I've updated this pull request to add a bit of documentation to those who might be wondering how do do this in #27 .

I've additionally added a debug option to print the rspec commands generated for each code lense since it was helpful for me to troubleshoot my configuration and contribute. I'm fine leaving this bit out though if it does not feel generally helpful.

Copy link
Owner

@st0012 st0012 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the context 👍
I think we can apply these changes to make the CI pass:

diff --git a/lib/ruby_lsp/ruby_lsp_rspec/addon.rb b/lib/ruby_lsp/ruby_lsp_rspec/addon.rb
index 1719e8f..83136a0 100644
--- a/lib/ruby_lsp/ruby_lsp_rspec/addon.rb
+++ b/lib/ruby_lsp/ruby_lsp_rspec/addon.rb
@@ -14,7 +14,8 @@ module RubyLsp
     class Addon < ::RubyLsp::Addon
       extend T::Sig
 
-      attr_reader :debug, :rspec_command
+      sig { returns(T.nilable(String)) }
+      attr_reader :rspec_command
 
       sig { override.params(global_state: GlobalState, message_queue: Thread::Queue).void }
       def activate(global_state, message_queue)
@@ -22,7 +23,7 @@ module RubyLsp
 
         settings = global_state.settings_for_addon(name)
         @rspec_command = T.let(settings&.dig(:rspecCommand), T.nilable(String))
-        @debug = T.let(settings&.dig(:debug) || false, T::Boolean)
+        @debug = T.let(settings&.dig(:debug) || false, T.nilable(T::Boolean))
       end
 
       sig { override.void }
@@ -44,7 +45,7 @@ module RubyLsp
       def create_code_lens_listener(response_builder, uri, dispatcher)
         return unless uri.to_standardized_path&.end_with?("_test.rb") || uri.to_standardized_path&.end_with?("_spec.rb")
 
-        CodeLens.new(response_builder, uri, dispatcher, rspec_command: rspec_command, debug: debug)
+        CodeLens.new(response_builder, uri, dispatcher, rspec_command: @rspec_command, debug: T.must(@debug))
       end
 
       sig do
diff --git a/spec/code_lens_spec.rb b/spec/code_lens_spec.rb
index c3d6883..c0a4974 100644
--- a/spec/code_lens_spec.rb
+++ b/spec/code_lens_spec.rb
@@ -164,7 +164,7 @@ RSpec.describe RubyLsp::RSpec do
     context "with a custom rspec command configured" do
       let(:configuration) do
         {
-          rspecCommand: "docker compose run --rm web rspec"
+          rspecCommand: "docker compose run --rm web rspec",
         }
       end
 
@@ -192,7 +192,7 @@ RSpec.describe RubyLsp::RSpec do
             },
           )
 
-          response = server.pop_response.response
+          response = pop_result(server).response
           expect(response[0].command.arguments[2]).to eq("docker compose run --rm web rspec /fake_spec.rb:1")
         end

Can you also update PR description to reflect the latest changes? Thanks.

@st0012 st0012 added the enhancement New feature or request label Feb 2, 2025
@westonkd
Copy link
Contributor Author

westonkd commented Feb 3, 2025

Done. Thanks @st0012 !

Running rspec, rubocop and sorbet tc are passing for me locally now. I'll keep an eye out for the results of the action once it runs.

Copy link
Owner

@st0012 st0012 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks 👍

@st0012 st0012 merged commit b590aac into st0012:main Feb 3, 2025
4 checks passed
@westonkd westonkd deleted the custom-rspec-command branch February 3, 2025 20:18
@pprotas
Copy link

pprotas commented Feb 17, 2025

Very unfortunate the relative path feature got reverted, I could really use this! Shopify/ruby-lsp#2965

My setup has the rails server running in Docker, but the VSC instance is local (not using devcontainer). Relative paths for test runners would really solve my issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants