diff --git a/ale_linters/eruby/erblint.vim b/ale_linters/eruby/erblint.vim new file mode 100644 index 00000000..19960185 --- /dev/null +++ b/ale_linters/eruby/erblint.vim @@ -0,0 +1,51 @@ +" Author: Roeland Moors - https://github.com/roelandmoors +" based on the ale ruumba and robocop linters +" Description: ERB Lint, support for https://github.com/Shopify/erb-lint + +call ale#Set('eruby_erblint_executable', 'erblint') +call ale#Set('eruby_erblint_options', '') + +function! ale_linters#eruby#erblint#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'eruby_erblint_executable') + + return ale#ruby#EscapeExecutable(l:executable, 'erblint') + \ . ' --format json ' + \ . ale#Var(a:buffer, 'eruby_erblint_options') + \ . ' --stdin %s' +endfunction + +function! ale_linters#eruby#erblint#Handle(buffer, lines) abort + if empty(a:lines) + return [] + endif + + let l:errors = ale#util#FuzzyJSONDecode(a:lines[0], []) + + if !has_key(l:errors, 'summary') + \|| l:errors['summary']['offenses'] == 0 + \|| empty(l:errors['files']) + return [] + endif + + let l:output = [] + + for l:error in l:errors['files'][0]['offenses'] + call add(l:output, { + \ 'lnum': l:error['location']['start_line'] + 0, + \ 'col': l:error['location']['start_column'] + 0, + \ 'end_col': l:error['location']['last_column'] + 0, + \ 'code': l:error['linter'], + \ 'text': l:error['message'], + \ 'type': 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('eruby', { +\ 'name': 'erblint', +\ 'executable': {b -> ale#Var(b, 'eruby_erblint_executable')}, +\ 'command': function('ale_linters#eruby#erblint#GetCommand'), +\ 'callback': 'ale_linters#eruby#erblint#Handle', +\}) diff --git a/doc/ale-eruby.txt b/doc/ale-eruby.txt index d75d3868..48a34895 100644 --- a/doc/ale-eruby.txt +++ b/doc/ale-eruby.txt @@ -4,6 +4,7 @@ ALE Eruby Integration *ale-eruby-options* There are four linters for `eruby` files: - `erb` +- `erblint` - `erubis` - `erubi` - `ruumba` @@ -13,6 +14,26 @@ default parser in Rails between 3.0 and 5.1. `erubi` is the default in Rails 5.1 and later. `ruumba` can extract Ruby from eruby files and run rubocop on the result. To selectively enable a subset, see |g:ale_linters|. +=============================================================================== +erblint *ale-eruby-erblint* + +g:ale_eruby_erblint_executable *g:ale_eruby_erblint_executable* + *b:ale_eruby_erblint_executable* + Type: |String| + Default: `'erblint'` + + Override the invoked erblint binary. This is useful for running erblint + from binstubs or a bundle. + + +g:ale_eruby_erblint_options *g:ale_ruby_erblint_options* + *b:ale_ruby_erblint_options* + Type: |String| + Default: `''` + + This variable can be change to modify flags given to erblint. + + =============================================================================== ruumba *ale-eruby-ruumba* diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 5617b33d..f98f9101 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -151,6 +151,7 @@ Notes: * `elm-make` * Erb * `erb` + * `erblint` * `erubi` * `erubis` * `ruumba` diff --git a/doc/ale.txt b/doc/ale.txt index f58dba01..97242748 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2729,6 +2729,7 @@ documented in additional help files. erlfmt................................|ale-erlang-erlfmt| syntaxerl.............................|ale-erlang-syntaxerl| eruby...................................|ale-eruby-options| + erblint...............................|ale-eruby-erblint| ruumba................................|ale-eruby-ruumba| fish....................................|ale-fish-options| fish_indent...........................|ale-fish-fish_indent| diff --git a/supported-tools.md b/supported-tools.md index f6e7dbc5..f643be5f 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -160,6 +160,7 @@ formatting. * [elm-make](https://github.com/elm/compiler) * Erb * [erb](https://apidock.com/ruby/ERB) + * [erblint](https://github.com/Shopify/erb-lint) * [erubi](https://github.com/jeremyevans/erubi) * [erubis](https://github.com/kwatch/erubis) * [ruumba](https://github.com/ericqweinstein/ruumba) diff --git a/test/handler/test_erblint_handler.vader b/test/handler/test_erblint_handler.vader new file mode 100644 index 00000000..01d4c0ab --- /dev/null +++ b/test/handler/test_erblint_handler.vader @@ -0,0 +1,70 @@ +Before: + runtime ale_linters/eruby/erblint.vim + +After: + unlet! g:lines + call ale#linter#Reset() + +Execute(The erblint handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'col': 0, + \ 'end_col': 0, + \ 'text': 'Extra blank line detected.', + \ 'code': 'ExtraNewline', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 6, + \ 'col': 0, + \ 'end_col': 0, + \ 'text': 'Remove multiple trailing newline at the end of the file.', + \ 'code': 'FinalNewline', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 9, + \ 'end_col': 11, + \ 'text': 'Use 1 space after `<%=` instead of 2 spaces.', + \ 'code': 'SpaceAroundErbTag', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 9, + \ 'end_col': 11, + \ 'text': 'Use 1 space before `%>` instead of 2 spaces.', + \ 'code': 'SpaceAroundErbTag', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 6, + \ 'end_col': 10, + \ 'text': 'Extra whitespace detected at end of line.', + \ 'code': 'TrailingWhitespace', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#eruby#erblint#Handle(347, [ + \ '{"metadata":{"erb_lint_version":"0.1.1","ruby_engine":"ruby","ruby_version":"3.0.2","ruby_patchlevel":"107","ruby_platform":"arm64-darwin20"},"files":[{"path":"demo.html.erb","offenses":[{"linter":"ExtraNewline","message":"Extra blank line detected.","location":{"start_line":3,"start_column":0,"last_line":4,"last_column":0,"length":1}},{"linter":"FinalNewline","message":"Remove multiple trailing newline at the end of the file.","location":{"start_line":6,"start_column":0,"last_line":8,"last_column":0,"length":2}},{"linter":"SpaceAroundErbTag","message":"Use 1 space after `<%=` instead of 2 spaces.","location":{"start_line":4,"start_column":9,"last_line":4,"last_column":11,"length":2}},{"linter":"SpaceAroundErbTag","message":"Use 1 space before `%>` instead of 2 spaces.","location":{"start_line":4,"start_column":9,"last_line":4,"last_column":11,"length":2}},{"linter":"TrailingWhitespace","message":"Extra whitespace detected at end of line.","location":{"start_line":5,"start_column":6,"last_line":5,"last_column":10,"length":4}}]}],"summary":{"offenses":5,"inspected_files":1,"corrected":0}}' + \ ]) + +Execute(The erblint handler should handle when files are checked and no offenses are found): + AssertEqual + \ [], + \ ale_linters#eruby#erblint#Handle(347, [ + \ '{"metadata":{"erb_lint_version":"0.1.1","ruby_engine":"ruby","ruby_version":"3.0.2","ruby_patchlevel":"107","ruby_platform":"arm64-darwin20"},"files":[{"path":"demo.html.erb","offenses":[]}],"summary":{"offenses":0,"inspected_files":1,"corrected":0}}' + \ ]) + +Execute(The erblint handler should handle output without any errors): + AssertEqual + \ [], + \ ale_linters#eruby#erblint#Handle(347, ['{}']) + + AssertEqual + \ [], + \ ale_linters#eruby#erblint#Handle(347, []) diff --git a/test/linter/test_erblint.vader b/test/linter/test_erblint.vader new file mode 100644 index 00000000..147b5965 --- /dev/null +++ b/test/linter/test_erblint.vader @@ -0,0 +1,26 @@ +Before: + call ale#assert#SetUpLinterTest('eruby', 'erblint') + call ale#test#SetFilename('dummy.html.erb') + + let g:ale_eruby_erblint_executable = 'erblint' + let g:ale_eruby_erblint_options = '' + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to erblint): + AssertLinter 'erblint', ale#Escape('erblint') + \ . ' --format json --stdin %s' + +Execute(Should be able to set a custom executable): + let g:ale_eruby_erblint_executable = 'bin/erblint' + + AssertLinter 'bin/erblint' , ale#Escape('bin/erblint') + \ . ' --format json --stdin %s' + +Execute(Setting bundle appends 'exec erblint'): + let g:ale_eruby_erblint_executable = 'path to/bundle' + + AssertLinter 'path to/bundle', ale#Escape('path to/bundle') + \ . ' exec erblint' + \ . ' --format json --stdin %s'