Skip to content
This repository has been archived by the owner on Jul 31, 2023. It is now read-only.

rubocop not using .rubocop.yml file #578

Open
Zhorian opened this issue Dec 29, 2019 · 35 comments
Open

rubocop not using .rubocop.yml file #578

Zhorian opened this issue Dec 29, 2019 · 35 comments

Comments

@Zhorian
Copy link

Zhorian commented Dec 29, 2019

Your environment

  • vscode-ruby version: 0.26.0
  • Ruby version: 2.6.3p62
  • Ruby version manager (if any): 1.29.9
  • VS Code version: 1.41.1
  • Operating System: Linux Mint 19.3
  • Using language server? (eg useLanguageServer is true?) true

Expected behavior

I'm expecting test/test_helper.rb to be ignored by rubocop based on my .rubocop.yml file. Confirmed config file is being used when running rubocop from the command line.

Actual behavior

I am still receiving linting errors on the for test/test_helper.rb

This and the next section should include screenshots, code samples, console output, etc. The more information we have to reproduce the better!

settings.json
{ "editor.formatOnSave": true, "editor.formatOnSaveTimeout": 5000, "powermode.enabled": true, "powermode.enableShake": false, "ruby.useLanguageServer": true, "ruby.lint": { "rubocop": true }, "ruby.format": "rubocop", "sync.gist": "d1b8c7400637948e668f4c6d174c5edb", "workbench.colorTheme": "Blueberry Banana", "workbench.iconTheme": "vscode-icons", }

.rubocop.yml
AllCops: TargetRubyVersion: 2.6.3 Exclude: - "**/*.erb" - db/schema.rb - "bin/**/*" - "node_modules/**/*" - test/test_helper.rb - test/channels/application_cable/connection_test.rb

image

@Zhorian
Copy link
Author

Zhorian commented Jan 4, 2020

Interestingly this seems to occur when using Solargraph diagnostics too!

@andrewmcodes
Copy link

Try turning the bundler option on. I’m not sure if the gem will automatically find the config file in your directory instead of looking globally.

https://github.com/rubyide/vscode-ruby/blob/master/docs/linting.md#configuration-options

@Zhorian
Copy link
Author

Zhorian commented Jan 9, 2020

I've updated my ruby lint settings to below and the issue persists.

"ruby.lint": { "rubocop": { "command": "rubocop", "useBundler": true, } },

@artm
Copy link

artm commented Jan 10, 2020

"useBundler": true is ignored when "command" is given.

@artm
Copy link

artm commented Jan 10, 2020

Context

I had a similar problem but in a somewhat convoluted environment, which I was able to investigate and solve, but my solution is convoluted as well :-) Perhaps @Zhorian's situation is similar in some respect?

My VSCode runs on a windows host connecting via remote ssh extension to a linux developmen VM inside which ruby environments are run in docker containers with docker-compose, so VSCode doesn't have direct access to any ruby commands.

Solving the problem in my context

In order to help linter execute rubocop inside my environment I made a project specific wrapper script inside the project's bin directory and corresponding linter config:

    "ruby.lint": {
        "rubocop": {
            "command": "bin/vscode-rubocop"
        }
    },

My first attempt suffered from this issue (rubocop not respecting .rubocop.yml:

#!/bin/bash
docker-compose exec -T application rubocop "$@"

This happens because of the way linter calls the script (according to the output in the Output view:

Lint: executing bin/vscode-rubocop -s /home/artm/src/project/app/controllers/application_controller.rb -f json

current contents of the file is sent on the stdin (rubocop's -s option) along with the absolute path to the file on the VM's filesystem. But since rubocop is running in a container the same file is available under a different absolute path (/app/app/controllers/application_controller.rb which corresponds to the same relative path because the project directory is mounted to /app. So I adjusted the wrapper script to strip current path prefix from every argument:

#!/bin/bash
docker-compose exec -T application rubocop "${@#$(pwd)/}"

This made rubocop respect .rubocop.yml because now it knows the file path and can find the corresponding configuration file(s).

Suggestions for the extension config

  • pass source paths relative to the project root
  • run 'command' + args via shell instead of assuming it's a name of executable, so we could configure something like:
    "ruby.lint": {
        "rubocop": {
            "command": "docker-compose exec -T spring spring rubocop",
            "relativeSourcePaths": true
        }
    },

It would also be nice if it was possible to reuse linter rubocop config in the ruby formatter config, or at least if it supported the same options. As far as I could figure out it is impossible to configure the formatter for my situation now.

P.S.

The final version of my wrapper script:

#!/bin/bash
docker-compose exec -T spring spring rubocop "${@#$(pwd)/}"

Which makes linter a bit faster. This relies on a spring server running inside a service called spring and spring-commands-rubocop being available in the project's bundle.

@Zhorian
Copy link
Author

Zhorian commented Jan 12, 2020

I resolved the issue. I added a .rubocop file (not .rubocop.yml) and added the following.

--force-exclusion

@januszm
Copy link

januszm commented Mar 8, 2021

Is creating the .rubocop file with --force-exclusion the official solution? I ran into this problem with vscode ignoring local .rubocop.yml and so far it's the only solution that helps (I've also considered creating a bin/rubocop wrapper but it's simpler)

@Zhorian
Copy link
Author

Zhorian commented Mar 8, 2021

I think adding this to your .vscode/settings.json is the prescribed way of doing this. This is how I've done it in my recent project.

  "ruby.lint": {
    "rubocop": {
      "forceExclusion": true,
    }
  }

@AlecRust
Copy link

AlecRust commented Mar 8, 2021

forceInclusion method no longer works for me or others, see #227.

My schema.rb has Rubocop errors even though it's excluded in .rubocop.yml:

AllCops:
  NewCops: enable
  Exclude:
    - db/schema.rb

@Zhorian
Copy link
Author

Zhorian commented Mar 8, 2021

I had that exact same issue! I ended up doing this which might be a bit overkill

AllCops:
  Exclude:
    - "node_modules/**/*"
    - "tmp/**/*"
    - "vendor/**/*"
    - ".git/**/*"
    - "db/**/*"
    - bin/**/*

@januszm
Copy link

januszm commented Mar 8, 2021

I just checked and indeed, none of the solutions (with .vscode/settings.json or .rubocop files) works if I combine AllCops exclusion with specific cop exclusion, like:

AllCops:
  Exclude:
    - vendor/**/*
    - db/schema.rb
    - db/migrate/*.rb
# ...
Metrics/BlockLength:
  Enabled: true
  Exclude:
    - spec/**/*
    - config/routes.rb

with the above configuration, rubocop is happy when I run it from shell, but complains about BlockLength in routes.rb in VsCode editor window

@AlexVPopov
Copy link

I can also confirm the issue occurs even with "forceExclusion": true. @Zhorian Could you, please, reopen the issue?

@AlexVPopov
Copy link

Hey @Zhorian , sorry, it seems that "useBundler": true was causing the problem on my side, no need to reopen the issue.

@lobo-tuerto
Copy link

lobo-tuerto commented Jun 18, 2021

I have this on my settings.json file for VSCode:

"ruby.lint": {
  "rubocop": true
},

And my .rubocop.yml is being ignored.
Is there any way to specify which path the config file can be found?
Or any pointers on how to configure it so it'll pick up the yml file at the project's root?


UPDATE:

I used @Zhorian code, and it seems to be working now:

"ruby.lint": {
  "rubocop": {
    "forceExclusion": true,
  }
}

@Zhorian Zhorian reopened this Oct 6, 2021
@Zhorian
Copy link
Author

Zhorian commented Oct 6, 2021

It's stopped working for me now.

@Zhorian Zhorian closed this as completed Oct 6, 2021
@AlecRust
Copy link

AlecRust commented Oct 6, 2021

I think #742 may fix this which is pending release.

@Zhorian could you reopen this issue?

@Zhorian Zhorian reopened this Oct 11, 2021
@AlexWayfer
Copy link

Is something blocking a new release? We can't use RuboCop in VSC almost for 2 years.

@gregawoods
Copy link

In order to help linter execute rubocop inside my environment I made a project specific wrapper script inside the project's bin directory and corresponding linter config:

    "ruby.lint": {
        "rubocop": {
            "command": "bin/vscode-rubocop"
        }
    },

@artm How did you get this wrapper script to be found with a relative path? Mine throws an error of unable to execute [snip] as the command could not be found.

It works if I use an absolute path to the script. However, I'm trying to set this up in a relative way so that it can be shared across users and environments.

I also tried using ${workspaceRoot} as described in #187 but that didn't work either.

Would really love to get rubocop working in docker compose!

@tgaeta
Copy link

tgaeta commented Jan 30, 2022

If you find that Rubocop works, but you're still getting warnings and tooltips in VS Code, try this:

"ruby.rubocop.suppressRubocopWarnings": true

@scorphus
Copy link

Sorry for the extra noise earlier.

I'm working on what is arguably my ugliest hack in recent times 😄 I'm not quite sure it works, but it seems to work for me.

First, create the following script anywhere on your PATH:

#!/usr/bin/env bash -li

arg_parts=(${@//\'/})
rubocop -s ${arg_parts[1]} -f json --force-exclusion

Then, use it as command:

    "ruby.lint": {
      "rubocop": {
        "command": "myrubocop"
      },

I hope it works for someone else too.

@soumyaray
Copy link

I'm having the same issue and I've tried everything in this thread except wrapping rubocop in my own script -- I just don't think that approach is suitable on collaborative projects. Is there an official way to resolve this issue yet?

@benzado
Copy link

benzado commented Apr 20, 2022

I've just fixed my local setup using a shim script and I think I've found a clue nobody has mentioned in the earlier comments... vscode-ruby is calling my script with these arguments: -s '/absolute/path/to/file.rb' -f json

I thought that the absolute path was the issue, so I wrote a script similar to this one by @artm. But the workspace path wasn't being stripped off the front of the path... then I realized that the single quotes ' around the path are part of the argument string.

Normally, if you typed rubocop 'file.rb' at the command line, the parser would strip away the quotes and the running script would see file.rb as its first argument. But the vscode-ruby extension is wrapping the path with quotes and then, instead of running it through a shell, passing the quoted string directly via an exec function or something like it.

The net result is that even though RuboCop can find its config files and is smart enough to figure out relative vs absolute paths, an exclusion pattern like test/foo/* won't match a path string like 'test/foo/bar.rb' because test doesn't match 'test.

Here's the shim script I'm using:

#!/bin/sh
# called with args like: -s '/path/to/file.rb' -f json
source_path=${2#\'} # strip leading quote
source_path=${source_path%\'} # strip trailing quote
/path/to/bundle exec rubocop -s "$source_path" -f json

I'm using extension v0.28.1.

Surely enough, on line 61 of RuboCop.ts you can see that it's wrapping the pathname with single quotes. That was introduced by commit d432fee which was trying to support (incorrectly) spaces in paths.

That change was undone by commit 18d5a00, which was added to fix #719, which appears to be a duplicate of this issue.

That commit is on the main branch but hasn't been released yet.

Based on my research, I think this issue should be closed as fixed by PR #720. The problem is that the project is overdue for a release, because it doesn't have an active maintainer.

@github-actions
Copy link

This issue has not had activity for 30 days. It will be automatically closed in 30 days.

@github-actions github-actions bot added the stale label Aug 19, 2022
@AlexWayfer
Copy link

This issue is still an issue. Probably, this bot should be disabled due to #815.

@github-actions github-actions bot removed the stale label Aug 20, 2022
@ricardograca
Copy link

According to my testing it seems that any exclusion pattern that points to a specific file name won't work. For example, if we have a file named file.rb with a Metrics/BlockLength linting error and I use this rule in .rubocop.yml, then it won't actually be ignored:

Metrics/BlockLength:
  Exclude: 
    - '**/file.rb'

But, if I move the file to the lib directory and change the exclusion pattern like so, the linting errors will be ignored:

Metrics/BlockLength:
  Exclude: 
    - '**/lib/*'

I can confirm that @benzado's conclusion is correct and #720 does indeed fix the issue, since I manually edited the file ~/.vscode/extensions/rebornix.ruby-0.28.1/dist/server/index.js replacing

`'${i.URI.parse(this.document.uri).fsPath}'`

with:

i.URI.parse(this.document.uri).fsPath

and single file exclusion patterns are now working (after restarting VSCode).

@y-amadatsu
Copy link

I made the same modification as @ricardograca and the .rubocop.yml setting is reflected.
Thank you @ricardograca !

@ricardograca
Copy link

That was supposed to be only a test, but indeed it does the trick until we get a more permanent solution.

@gregawoods
Copy link

Worked for me too, I finally see rubocop ignoring Metrics/BlockLength in my rspec files. 🥳

@m-o-e
Copy link

m-o-e commented Oct 16, 2022

The solution by @ricardograca worked for me as well. Thank you!

You can use this oneliner to apply his fix (VSCode must be restarted afterwards):

sed -i .bak "s/\`'\${i.URI.parse(this.document.uri).fsPath}'\`/i.URI.parse(this.document.uri).fsPath/g" ~/.vscode/extensions/rebornix.ruby-0.28.1/dist/server/index.js

It will save a backup of the original file to index.js.bak.

@gregawoods
Copy link

I've been using the solution here for a while and it's been good so far. I noticed this morning however that it isn't working with AllCops rules. For example, I'm now seeing BlockLength errors in routes.rb despite it being excluded.

This does not work:

AllCops:
  Exclude:
    - 'config/**/*'

But this works:

Metrics/BlockLength:
  Exclude:
    - 'config/**/*'

I wonder, when could we get at least the partial fix officially released?

@mcelicalderon
Copy link

Thank you, @ricardograca and @m-o-e! I can confirm #578 (comment) worked for me 🙌 at least for some cops. Not sure if I will run into something else as described in #578 (comment)

@github-actions
Copy link

This issue has not had activity for 30 days. It will be automatically closed in 30 days.

@github-actions github-actions bot added the stale label Mar 23, 2023
@AlexWayfer
Copy link

This issue has not had activity for 30 days. It will be automatically closed in 30 days.

We're waiting for 2+ years, bots interfer, forcing to flood useless messages like this one.

@github-actions github-actions bot removed the stale label Mar 24, 2023
@severinraez
Copy link

On Ubuntu, I had to adapt the command from @m-o-e to

sed -i.bak "s/\`'\${i.URI.parse(this.document.uri).fsPath}'\`/i.URI.parse(this.document.uri).fsPath/g" ~/.vscode/extensions/rebornix.ruby-0.28.1/dist/server/index.js

(removed the space between -i and .bak, might be a macOS vs linux issue).

@januszm
Copy link

januszm commented Jul 6, 2023

On Ubuntu, I had to adapt the command from @m-o-e to
(removed the space between -i and .bak, might be a macOS vs linux issue).

And here's the explanation why: https://unix.stackexchange.com/questions/281543/is-my-interpretation-of-sed-i-bak-x-d-some-file-correct

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests