VIM version
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Feb 12 2018 14:37:54)
Included patches: 1-2
Operating System: CentOS 6
Current Filetype: ruby
Available Linters: ['brakeman', 'rails_best_practices', 'reek', 'rubocop', 'ruby']
Enabled Linters: ['rubocop', 'ruby']
Linter Variables:
let g:ale_ruby_rubocop_executable = '/export/home/ryanma/.gem/ruby/2.4.0/bin/rubocop'
let g:ale_ruby_rubocop_options = ''
let g:ale_ruby_ruby_executable = 'ruby'
Global Variables:
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {'ruby': ['rubocop']}
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'always'
let g:ale_linter_aliases = {}
let g:ale_linters = {'ruby': ['ruby', 'rubocop']}
let g:ale_open_list = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 1
let g:ale_sign_error = '>>'
let g:ale_sign_offset = 1000000
let g:ale_sign_warning = '--'
let g:ale_statusline_format = ['%d error(s)', '%d warning(s)', 'OK']
let g:ale_warn_about_trailing_whitespace = 1
Command History:
(executable check - success) /export/home/ryanma/.gem/ruby/2.4.0/bin/rubocop
(finished - exit code 1) ['/bin/bash', '-c', '''/export/home/ryanma/.gem/ruby/2.4.0/bin/rubocop'' --format json --force-exclusion --stdin ''<path_to_file>/config/deploy.rb'' < ''/tmp/vEUIODm/5/deploy.rb''']
<<<NO OUTPUT RETURNED>>>
(executable check - success) ruby
(finished - exit code 0) ['/bin/bash', '-c', '''ruby'' -w -c -T1 ''/tmp/vEUIODm/6/deploy.rb''']
<<<NO OUTPUT RETURNED>>>
ALE with Rubocop seem to be having issues reading the current buffer.
ruby as a linter works fine, and running /bin/bash -c '''/export/home/ryanma/.gem/ruby/2.4.0/bin/rubocop'' --format json --force-exclusion --stdin ''<path_to_file>/config/deploy.rb'' < ''<path_to_file>/config/deploy.rb''' works and prints out the errors the file has/tmp/ directory$PATHI'm not entirely sure how to reproduce this, unfortunately. Mostly looking for more help to diagnose the setup
@ryanma Have you tried generating rubocop's binstubs?
From your project directory:
$ bundle binstubs rubocop
Thanks for leaving a comment. I don't use Ruby myself.
@ryanma I was able to fix this issue by setting let g:ale_ruby_rubocop_executable = 'bin/rubocop'. This relies on having a binstub for RuboCop generated. For some reason, let g:ale_ruby_rubocop_executable = 'bundle exec rubocop' does not work.
@w0rp I was poking through https://github.com/w0rp/ale/blob/master/ale_linters/ruby/rubocop.vim, and I think I have identified the issue, at least partially. The issue has to do with how the command is being checked and built.
function! ale_linters#ruby#rubocop#GetCommand(buffer) abort
let l:executable = ale#handlers#rubocop#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'bundle$'
\ ? ' exec rubocop'
\ : ''
return ale#Escape(l:executable) . l:exec_args
\ . ' --format json --force-exclusion '
\ . ale#Var(a:buffer, 'ruby_rubocop_options')
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))
endfunction
Based on this, setting let g:ale_ruby_rubocop_executable = 'bundle' will get bundle exec rubocop to work. RuboCop and rails_best_practices appear to have the same bug with setting bundle as the executable. Reek and Brakeman don't appear to have settings to change the executable.
Ruby gems can be installed at the system level or locally through bundler. System level gems can be executed like normal commands. Locally installed gems can be run via bundle exec <command_name>. If a binstub is generated for the locally installed gem, bin/<command_name> can be used.
I think it would be beneficial to have some auto-detection of if a binstub exists and to use it if present. Additionally/alternatively, it would be beneficial to have a setting to use bundle exec for all Ruby commands. vim-test has some auto-detection and config settings that work similar to this.
Command run by ale_linters#ruby#rubocop#GetCommand with different settings
g:ale_ruby_rubocop_executable not set in vimrc - Works with system install
'rubocop' --format json --force-exclusion --stdin ''
let g:ale_ruby_rubocop_executable = 'bin/rubocop' - Work with binstub
'bin/rubocop' --format json --force-exclusion --stdin ''
let g:ale_ruby_rubocop_executable = 'bundle' - works with bundle exec
'bundle' exec rubocop --format json --force-exclusion --stdin ''
let g:ale_ruby_rubocop_executable = 'bundle exec rubocop' - does not work
'bundle exec rubocop' --format json --force-exclusion --stdin ''
I'm not that good with vimscript, but I would be willing to try fixing or working with someone to fix this.
Okay. Note that vim-test allows _executable options to be commands, but ALE _executable options should be only a path to an executable.
ALE
_executableoptions should be only a path to an executable.
I did not realize that. Now it makes sense why setting let g:ale_ruby_rubocop_executable = 'bundle exec rubocop' does not work.
Looking through the documentation again, the section for rails_best_practices mentions setting the executable to bundle, however the documentation for rubocop does not mention this.
g:ale_ruby_rails_best_practices_executable
g:ale_ruby_rails_best_practices_executable
b:ale_ruby_rails_best_practices_executable
Type: String
Default: 'rails_best_practices'
Override the invoked rails_best_practices binary. Set this to 'bundle' to
invoke 'bundle exec rails_best_practices'.
I think this can be improved mostly by updating documentation, and by updating Reek and Brakeman to have consistent settings to RuboCop and rails_best_practices.
The rubygems-bundler gem aims to fix this kind of issue: it will make calling foo as bundle exec foo automatic if a Gemfile is present, and otherwise falls back to be the globally installed foo.
Most helpful comment
@ryanma I was able to fix this issue by setting
let g:ale_ruby_rubocop_executable = 'bin/rubocop'. This relies on having a binstub for RuboCop generated. For some reason,let g:ale_ruby_rubocop_executable = 'bundle exec rubocop'does not work.@w0rp I was poking through https://github.com/w0rp/ale/blob/master/ale_linters/ruby/rubocop.vim, and I think I have identified the issue, at least partially. The issue has to do with how the command is being checked and built.
Based on this, setting
let g:ale_ruby_rubocop_executable = 'bundle'will getbundle exec rubocopto work. RuboCop and rails_best_practices appear to have the same bug with settingbundleas the executable. Reek and Brakeman don't appear to have settings to change the executable.Ruby gems can be installed at the system level or locally through bundler. System level gems can be executed like normal commands. Locally installed gems can be run via
bundle exec <command_name>. If a binstub is generated for the locally installed gem,bin/<command_name>can be used.I think it would be beneficial to have some auto-detection of if a binstub exists and to use it if present. Additionally/alternatively, it would be beneficial to have a setting to use
bundle execfor all Ruby commands. vim-test has some auto-detection and config settings that work similar to this.Command run by
ale_linters#ruby#rubocop#GetCommandwith different settingsI'm not that good with vimscript, but I would be willing to try fixing or working with someone to fix this.