Shopify / ruby-lsp-rails

A Ruby LSP addon for Rails
https://shopify.github.io/ruby-lsp-rails/
MIT License
548 stars 24 forks source link

Controller code lens doesn't work alongside RSpec #409

Closed pauldruziak closed 2 months ago

pauldruziak commented 2 months ago

Description

I use vs code inside docker with ruby-lsp. Everything works find except code lens:

2024-07-15 11:40:36.550 [info] (test-app) [Trace - 11:40:36 AM] Sending request 'textDocument/codeLens - (10)'.
2024-07-15 11:40:36.550 [info] (test-app) Params: {
    "textDocument": {
        "uri": "file:///test-app/app/controllers/posts_controller.rb"
    }
}
2024-07-15 11:40:36.732 [info] (test-app) [Trace - 11:40:36 AM] Received response 'textDocument/codeLens - (10)' in 182ms.
2024-07-15 11:40:36.732 [info] (test-app) Result: []

I created a new rails app and scaffolded a PostController. So, nothing unusual here:

class PostsController < ApplicationController
  before_action :set_post, only: %i[ show edit update destroy ]

  # GET /posts or /posts.json
  def index
    @posts = Post.all
  end

  # GET /posts/1 or /posts/1.json
  def show
  end

  # GET /posts/new
  def new
    @post = Post.new
  end

  # GET /posts/1/edit
  def edit
  end

  # POST /posts or /posts.json
  def create
    @post = Post.new(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to post_url(@post), notice: "Post was successfully created." }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /posts/1 or /posts/1.json
  def update
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to post_url(@post), notice: "Post was successfully updated." }
        format.json { render :show, status: :ok, location: @post }
      else
        format.html { render :edit, status: :unprocessable_entity }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /posts/1 or /posts/1.json
  def destroy
    @post.destroy!

    respond_to do |format|
      format.html { redirect_to posts_url, notice: "Post was successfully destroyed." }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_post
      @post = Post.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def post_params
      params.require(:post).permit(:title, :body)
    end
end
GEM
  remote: https://rubygems.org/
  specs:
    actioncable (7.1.3.4)
      actionpack (= 7.1.3.4)
      activesupport (= 7.1.3.4)
      nio4r (~> 2.0)
      websocket-driver (>= 0.6.1)
      zeitwerk (~> 2.6)
    actionmailbox (7.1.3.4)
      actionpack (= 7.1.3.4)
      activejob (= 7.1.3.4)
      activerecord (= 7.1.3.4)
      activestorage (= 7.1.3.4)
      activesupport (= 7.1.3.4)
      mail (>= 2.7.1)
      net-imap
      net-pop
      net-smtp
    actionmailer (7.1.3.4)
      actionpack (= 7.1.3.4)
      actionview (= 7.1.3.4)
      activejob (= 7.1.3.4)
      activesupport (= 7.1.3.4)
      mail (~> 2.5, >= 2.5.4)
      net-imap
      net-pop
      net-smtp
      rails-dom-testing (~> 2.2)
    actionpack (7.1.3.4)
      actionview (= 7.1.3.4)
      activesupport (= 7.1.3.4)
      nokogiri (>= 1.8.5)
      racc
      rack (>= 2.2.4)
      rack-session (>= 1.0.1)
      rack-test (>= 0.6.3)
      rails-dom-testing (~> 2.2)
      rails-html-sanitizer (~> 1.6)
    actiontext (7.1.3.4)
      actionpack (= 7.1.3.4)
      activerecord (= 7.1.3.4)
      activestorage (= 7.1.3.4)
      activesupport (= 7.1.3.4)
      globalid (>= 0.6.0)
      nokogiri (>= 1.8.5)
    actionview (7.1.3.4)
      activesupport (= 7.1.3.4)
      builder (~> 3.1)
      erubi (~> 1.11)
      rails-dom-testing (~> 2.2)
      rails-html-sanitizer (~> 1.6)
    activejob (7.1.3.4)
      activesupport (= 7.1.3.4)
      globalid (>= 0.3.6)
    activemodel (7.1.3.4)
      activesupport (= 7.1.3.4)
    activerecord (7.1.3.4)
      activemodel (= 7.1.3.4)
      activesupport (= 7.1.3.4)
      timeout (>= 0.4.0)
    activestorage (7.1.3.4)
      actionpack (= 7.1.3.4)
      activejob (= 7.1.3.4)
      activerecord (= 7.1.3.4)
      activesupport (= 7.1.3.4)
      marcel (~> 1.0)
    activesupport (7.1.3.4)
      base64
      bigdecimal
      concurrent-ruby (~> 1.0, >= 1.0.2)
      connection_pool (>= 2.2.5)
      drb
      i18n (>= 1.6, < 2)
      minitest (>= 5.1)
      mutex_m
      tzinfo (~> 2.0)
    addressable (2.8.7)
      public_suffix (>= 2.0.2, < 7.0)
    ast (2.4.2)
    base64 (0.2.0)
    bigdecimal (3.1.8)
    bindex (0.8.1)
    bootsnap (1.18.3)
      msgpack (~> 1.2)
    builder (3.3.0)
    capybara (3.40.0)
      addressable
      matrix
      mini_mime (>= 0.1.3)
      nokogiri (~> 1.11)
      rack (>= 1.6.0)
      rack-test (>= 0.6.3)
      regexp_parser (>= 1.5, < 3.0)
      xpath (~> 3.2)
    concurrent-ruby (1.3.3)
    connection_pool (2.4.1)
    crass (1.0.6)
    date (3.3.4)
    debug (1.9.2)
      irb (~> 1.10)
      reline (>= 0.3.8)
    drb (2.2.1)
    erubi (1.13.0)
    globalid (1.2.1)
      activesupport (>= 6.1)
    i18n (1.14.5)
      concurrent-ruby (~> 1.0)
    importmap-rails (2.0.1)
      actionpack (>= 6.0.0)
      activesupport (>= 6.0.0)
      railties (>= 6.0.0)
    io-console (0.7.2)
    irb (1.14.0)
      rdoc (>= 4.0.0)
      reline (>= 0.4.2)
    jbuilder (2.12.0)
      actionview (>= 5.0.0)
      activesupport (>= 5.0.0)
    json (2.7.2)
    language_server-protocol (3.17.0.3)
    lint_roller (1.1.0)
    logger (1.6.0)
    loofah (2.22.0)
      crass (~> 1.0.2)
      nokogiri (>= 1.12.0)
    mail (2.8.1)
      mini_mime (>= 0.1.1)
      net-imap
      net-pop
      net-smtp
    marcel (1.0.4)
    matrix (0.4.2)
    mini_mime (1.1.5)
    minitest (5.24.1)
    msgpack (1.7.2)
    mutex_m (0.2.0)
    net-imap (0.4.14)
      date
      net-protocol
    net-pop (0.1.2)
      net-protocol
    net-protocol (0.2.2)
      timeout
    net-smtp (0.5.0)
      net-protocol
    nio4r (2.7.3)
    nokogiri (1.16.6-aarch64-linux)
      racc (~> 1.4)
    nokogiri (1.16.6-x86_64-linux)
      racc (~> 1.4)
    parallel (1.25.1)
    parser (3.3.4.0)
      ast (~> 2.4.1)
      racc
    prism (0.30.0)
    psych (5.1.2)
      stringio
    public_suffix (6.0.0)
    puma (6.4.2)
      nio4r (~> 2.0)
    racc (1.8.0)
    rack (3.1.7)
    rack-session (2.0.0)
      rack (>= 3.0.0)
    rack-test (2.1.0)
      rack (>= 1.3)
    rackup (2.1.0)
      rack (>= 3)
      webrick (~> 1.8)
    rails (7.1.3.4)
      actioncable (= 7.1.3.4)
      actionmailbox (= 7.1.3.4)
      actionmailer (= 7.1.3.4)
      actionpack (= 7.1.3.4)
      actiontext (= 7.1.3.4)
      actionview (= 7.1.3.4)
      activejob (= 7.1.3.4)
      activemodel (= 7.1.3.4)
      activerecord (= 7.1.3.4)
      activestorage (= 7.1.3.4)
      activesupport (= 7.1.3.4)
      bundler (>= 1.15.0)
      railties (= 7.1.3.4)
    rails-dom-testing (2.2.0)
      activesupport (>= 5.0.0)
      minitest
      nokogiri (>= 1.6)
    rails-html-sanitizer (1.6.0)
      loofah (~> 2.21)
      nokogiri (~> 1.14)
    railties (7.1.3.4)
      actionpack (= 7.1.3.4)
      activesupport (= 7.1.3.4)
      irb
      rackup (>= 1.0.0)
      rake (>= 12.2)
      thor (~> 1.0, >= 1.2.2)
      zeitwerk (~> 2.6)
    rainbow (3.1.1)
    rake (13.2.1)
    rbs (3.5.2)
      logger
    rdoc (6.7.0)
      psych (>= 4.0.0)
    regexp_parser (2.9.2)
    reline (0.5.9)
      io-console (~> 0.5)
    rexml (3.3.1)
      strscan
    rubocop (1.64.1)
      json (~> 2.3)
      language_server-protocol (>= 3.17.0)
      parallel (~> 1.10)
      parser (>= 3.3.0.2)
      rainbow (>= 2.2.2, < 4.0)
      regexp_parser (>= 1.8, < 3.0)
      rexml (>= 3.2.5, < 4.0)
      rubocop-ast (>= 1.31.1, < 2.0)
      ruby-progressbar (~> 1.7)
      unicode-display_width (>= 2.4.0, < 3.0)
    rubocop-ast (1.31.3)
      parser (>= 3.3.1.0)
    rubocop-performance (1.21.1)
      rubocop (>= 1.48.1, < 2.0)
      rubocop-ast (>= 1.31.1, < 2.0)
    ruby-lsp (0.17.7)
      language_server-protocol (~> 3.17.0)
      prism (>= 0.29.0, < 0.31)
      rbs (>= 3, < 4)
      sorbet-runtime (>= 0.5.10782)
    ruby-progressbar (1.13.0)
    rubyzip (2.3.2)
    selenium-webdriver (4.22.0)
      base64 (~> 0.2)
      logger (~> 1.4)
      rexml (~> 3.2, >= 3.2.5)
      rubyzip (>= 1.2.2, < 3.0)
      websocket (~> 1.0)
    sorbet-runtime (0.5.11481)
    sprockets (4.2.1)
      concurrent-ruby (~> 1.0)
      rack (>= 2.2.4, < 4)
    sprockets-rails (3.5.1)
      actionpack (>= 6.1)
      activesupport (>= 6.1)
      sprockets (>= 3.0.0)
    sqlite3 (1.7.3-aarch64-linux)
    sqlite3 (1.7.3-x86_64-linux)
    standard (1.39.1)
      language_server-protocol (~> 3.17.0.2)
      lint_roller (~> 1.0)
      rubocop (~> 1.64.0)
      standard-custom (~> 1.0.0)
      standard-performance (~> 1.4)
    standard-custom (1.0.2)
      lint_roller (~> 1.0)
      rubocop (~> 1.50)
    standard-performance (1.4.0)
      lint_roller (~> 1.1)
      rubocop-performance (~> 1.21.0)
    stimulus-rails (1.3.3)
      railties (>= 6.0.0)
    stringio (3.1.1)
    strscan (3.1.0)
    thor (1.3.1)
    timeout (0.4.1)
    turbo-rails (2.0.5)
      actionpack (>= 6.0.0)
      activejob (>= 6.0.0)
      railties (>= 6.0.0)
    tzinfo (2.0.6)
      concurrent-ruby (~> 1.0)
    unicode-display_width (2.5.0)
    web-console (4.2.1)
      actionview (>= 6.0.0)
      activemodel (>= 6.0.0)
      bindex (>= 0.4.0)
      railties (>= 6.0.0)
    webrick (1.8.1)
    websocket (1.2.11)
    websocket-driver (0.7.6)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.5)
    xpath (3.2.0)
      nokogiri (~> 1.8)
    zeitwerk (2.6.16)

PLATFORMS
  aarch64-linux
  x86_64-linux

DEPENDENCIES
  bootsnap
  capybara
  debug
  importmap-rails
  jbuilder
  puma (>= 5.0)
  rails (~> 7.1.3, >= 7.1.3.4)
  ruby-lsp
  selenium-webdriver
  sprockets-rails
  sqlite3 (~> 1.4)
  standard
  stimulus-rails
  turbo-rails
  tzinfo-data
  web-console

RUBY VERSION
   ruby 3.2.4p170

BUNDLED WITH
   2.4.19
andyw8 commented 2 months ago

@pauldruziak can you check which version of ruby-lsp-rails is active? It should show in the Ruby LSP output panel when it starts up.

pauldruziak commented 2 months ago

@andyw8

2024-07-15 14:07:06.535 [info] (test-app) Initializing Ruby LSP v0.17.7...

and just in case

    "clientInfo": {
        "name": "Visual Studio Code",
        "version": "1.91.1"
    },
andyw8 commented 2 months ago

@pauldruziak I was asking about ruby-lsp-rails, not ruby-lsp.

If you don't see it at all, then it may indicate a problem with it detecting that your repo is using Rails.

pauldruziak commented 2 months ago

@andyw8 oh, right. I can't find any lines related to ruby-lsp-rails. And when I run "Ruby LSP: Display addons" it also shows nothing.

pauldruziak commented 2 months ago

@andyw8 I added ruby-lsp-rails to Gemfile, and now I got:

2024-07-15 16:55:41.886 [info] (test-app) Activating Ruby LSP Rails addon v0.3.10

and code lens start working too

andyw8 commented 2 months ago

Thanks, you shouldn't need to manually add it though, it is automatically added to the .ruby-lsp/Gemfile when Rails is detected:

https://github.com/Shopify/ruby-lsp/blob/e7f54ad7da01b4f9a0a54399d37c8fd15875b4a1/lib/ruby_lsp/setup_bundler.rb#L151-L153

Is there a chance you can try it outside of Docker?

pauldruziak commented 2 months ago

@andyw8 in the test project:

  1. After I removed ruby-lsp and ruby-lsp-rails gems it stars working as expected
  2. But then I added ruby-lsp-rspec it stopped working again

In the working project: I removed all gems, and after that it stopped working. I see the line Activating Ruby LSP Rails addon v0.3.10, but codeLens still returns empty results Result: []

andyw8 commented 2 months ago

@pauldruziak I'm seeing that when ruby-lsp-rspec is added it does indeed cause the code lenses to no longer appear. Could you please log an issue for that in https://github.com/st0012/ruby-lsp-rspec? (cc @st0012).

I'll close the issue here for now, we can re-open if it turns out changes are needed in Ruby LSP.

andyw8 commented 2 months ago

^ Ignore the above, @st0012 has identified the cause. We need to make a change in ruby-lsp-rails. I will transfer the issue to that repo, then add further details.

andyw8 commented 2 months ago

Here's the problem:

Until recently, the only thing that code lenses were used for was on tests. And since ruby-lsp-rails only supports "rails" tests, we return early unless that's the test framework in use:

https://github.com/Shopify/ruby-lsp-rails/blob/e380769e7fb4a53c1310512e606026b206bc5b0e/lib/ruby_lsp/ruby_lsp_rails/addon.rb#L54

But now that we're also using code lenses for other purposes, we need to change this, e.g. to split this behaviour into two listeners, initialized separately.

vinistock commented 2 months ago

As a quicker fix, we can also just check for the test library inside code lens and then look into splitting listeners.

pauldruziak commented 2 months ago

There is some problem with rspec, but the original problem is unrelated to RSpec.

I removed all ruby-lsp gems from the Gemfile, and I see the next line:

2024-07-16 10:56:16.880 [info] (wealthbox) Finished initializing Ruby LSP!
Activating Ruby LSP Rails addon v0.3.10
Ruby LSP Rails booting server

but it still returns empty results:

2024-07-16 10:57:39.571 [info] (project) [Trace - 10:57:39 AM] Sending request 'textDocument/codeLens - (24)'.
2024-07-16 10:57:39.571 [info] (project) Params: {
    "textDocument": {
        "uri": "file:///project/app/controllers/users_controller.rb"
    }
}

2024-07-16 10:57:39.575 [info] (project) [Trace - 10:57:39 AM] Received response 'textDocument/codeLens - (24)' in 4ms.
2024-07-16 10:57:39.575 [info] (project) Result: []
vinistock commented 2 months ago

@pauldruziak try doing a quick edit in the file.

If a code lens request happens before the Rails runtime integration is running, we may end up caching the empty array as the result for that file. If you close and re-open or if you make an edit, you will bust the cache and it should show up.

pauldruziak commented 2 months ago

@vinistock it doens't help 😕