dense-analysis / ale

Check syntax in Vim/Neovim asynchronously and fix files, with Language Server Protocol (LSP) support
BSD 2-Clause "Simplified" License
13.52k stars 1.43k forks source link

ERB linter has erroneous errors in at least ruby 3.1.2 #4167

Open powersurge360 opened 2 years ago

powersurge360 commented 2 years ago

Information

VIM version

NVIM v0.7.0
Build type: Release

Operating System: macOS 12.3.1

What went wrong

Ruby 3.1.2 (and maybe all Ruby 3.x versions) have a deprecation message when using the eruby ALE linter in rails applications.

Specifically, the error message you get is:

Passing trim_mode with the 3rd argument of erb.new is deprecated.

This error message seems to come from ale itself and can be fixed by perhaps splitting based on ruby versions to use the older signature in older rubies and the newer signature in newer rubies.

Reproducing the bug

  1. Have a clone of a ruby application running ruby 3.1.2 and requisite dependencies
  2. Open an erb file
  3. Notice that all erb files have an error on the first line with the message Passing trim_mode with the 3rd argument of erb.new is deprecated

:ALEInfo

 Current Filetype: eruby
Available Linters: ['erb', 'erblint', 'erubi', 'erubis', 'ruumba']
   Linter Aliases:
'erb' -> ['erubylint']
  Enabled Linters: ['erb', 'erblint', 'erubi', 'erubis', 'ruumba']
  Ignored Linters: []
 Suggested Fixers: 
  'erblint' - Apply erblint --autocorrect to a file.
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
 Linter Variables:

let g:ale_eruby_erblint_executable = 'erblint'
let g:ale_eruby_erblint_options = ''
let g:ale_eruby_ruumba_executable = 'ruumba'
let g:ale_eruby_ruumba_options = ''
 Global Variables:

let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = 0
let g:ale_command_wrapper = ''
let g:ale_completion_delay = v:null
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = v:null
let g:ale_disable_lsp = 0
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_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 1
let g:ale_fixers = {'go': ['gofmt'], 'ruby': ['standardrb'], 'javascript': ['prettier'], 'css': ['prettier']}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
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_filetype_changed = 1
let g:ale_lint_on_insert_leave = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linter_aliases = {}
let g:ale_linters = {}
let g:ale_linters_explicit = 0
let g:ale_linters_ignore = {'ruby': ['rubocop']}
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 0
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_root = {}
let g:ale_set_balloons = 0
let g:ale_set_highlights = 0
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '>>'
let g:ale_sign_info = '--'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = '>>'
let g:ale_sign_style_warning = '--'
let g:ale_sign_warning = '--'
let g:ale_sign_highlight_linenrs = 0
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
  Command History:

(executable check - success) erb
(started) ['/bin/zsh', '-c', 'ruby -r erb -e ''puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src''< ''/var/folders/6v/d3rhg9yd7vq4dpx9fbj2v9hh0000gn/T/nvimtnUgQQ/29/new.html.erb'' | ruby -c']
(executable check - failure) erblint
(started) ['/bin/zsh', '-c', 'ruby -r erubi/capture_end -e ''""''']
(executable check - failure) erubis
(executable check - failure) ruumba
(finished - exit code 0) ['/bin/zsh', '-c', 'ruby -r erb -e ''puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src''< ''/var/folders/6v/d3rhg9yd7vq4dpx9fbj2v9hh0000gn/T/nvimtnUgQQ/30/new.html.erb'' | ruby -c']

<<<OUTPUT STARTS>>>
-e:1: warning: Passing safe_level with the 2nd argument of ERB.new is deprecated. Do not use it, and specify other arguments as keyword arguments.
-e:1: warning: Passing trim_mode with the 3rd argument of ERB.new is deprecated. Use keyword argument like ERB.new(str, trim_mode: ...) instead.
<<<OUTPUT ENDS>>>

(executable check - failure) erblint
(finished - exit code 0) ['/bin/zsh', '-c', 'ruby -r erubi/capture_end -e ''""''']

<<<NO OUTPUT RETURNED>>>

(executable check - failure) erubis
(executable check - failure) ruumba
(finished - exit code 0) ['/bin/zsh', '-c', 'ruby -r erubi/capture_end -e ''puts Erubi::CaptureEndEngine.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src''< ''/var/folders/6v/d3rhg9yd7vq4dpx9fbj2v9hh0000gn/T/nvimtnUgQQ/31/new.html.erb'' | ruby -c']

<<<OUTPUT STARTS>>>
Syntax OK
<<<OUTPUT ENDS>>>

I think the problem is in this line (finished - exit code 0) ['/bin/zsh', '-c', 'ruby -r erb -e ''puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src''< ''/var/folders/6v/d3rhg9yd7vq4dpx9fbj2v9hh0000gn/T/nvimtnUgQQ/30/new.html.erb'' | ruby -c']. The deprecation messages are also visible in the log.

powersurge360 commented 2 years ago

It looks like the invocation that corrects it is return 'ruby -r erb -e ' . ale#Escape('puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), trim_mode: %{-}).src') . '< %t | ruby -c' but I don't have a good grasp of what it's doing so I'm not sure. At least, it doesn't seem to have any deprecation warnings.

powersurge360 commented 2 years ago

I'm pretty green on VimScript, but if someone can point me towards where a solve like this has been implemented in the past, I can take a crack at fixing this myself. I imagine there's probably a utility written somewhere in the codebase that makes these version checks generic based on the executable.

hsanson commented 2 years ago

You can check ansible_lint.vim and vint.vim for examples on how to generate the command depending on the tool version.

duleorlovic commented 1 year ago

Workaround is to define your own function like https://github.com/dense-analysis/ale/blob/master/ale_linters/eruby/erb.vim It has to be in file with the path as the function name. So create a file inside this folder mkdir -p ~/.vim/ale_linters/eruby

" ~/.vim/ale_linters/eruby/erb.vim
function! ale_linters#eruby#erb#GetCommand(buffer) abort
    return 'ruby -r erb -e ' . ale#Escape('puts ERB.new($stdin.read.gsub(%{<%=},%{<%})).src') . '< %t | ruby -c'
endfunction

and include it in your .vimrc

" .vimrc
" overwrite default ERB linter untill this is fixed
" https://github.com/dense-analysis/ale/issues/4167
source ~/.vim/ale_linters/eruby/erb.vim