Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for Tlint - A Tighten Opinionated PHP Linter #3291

Merged
merged 10 commits into from
Nov 21, 2020
80 changes: 80 additions & 0 deletions ale_linters/php/tlint.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
" Author: Jose Soto <jose@tighten.co>
"
" Description: Tighten Opinionated PHP Linting
" Website: https://github.com/tightenco/tlint

call ale#Set('php_tlint_executable', 'tlint')
call ale#Set('php_tlint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('php_tlint_options', '')

function! ale_linters#php#tlint#GetProjectRoot(buffer) abort
let l:composer_path = ale#path#FindNearestFile(a:buffer, 'composer.json')

if !empty(l:composer_path)
return fnamemodify(l:composer_path, ':h')
endif

let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git')

return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : ''
endfunction

function! ale_linters#php#tlint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'php_tlint', [
\ 'vendor/bin/tlint',
\ 'tlint',
\])
endfunction

function! ale_linters#php#tlint#GetCommand(buffer) abort
let l:executable = ale_linters#php#tlint#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'php_tlint_options')

return ale#node#Executable(a:buffer, l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' lint %s'
endfunction

function! ale_linters#php#tlint#Handle(buffer, lines) abort
" Matches against lines like the following:
"
" ! There should be 1 space around `.` concatenations, and additional lines should always start with a `.`
" 22 : ` $something = 'a'.'name';`
"
let l:loop_count = 0
let l:messages_pattern = '^\! \(.*\)'
let l:output = []
let l:pattern = '^\(\d\+\) \:'
let l:temp_messages = []

for l:message in ale#util#GetMatches(a:lines, l:messages_pattern)
call add(l:temp_messages, l:message)
endfor

let l:loop_count = 0

for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:num = l:match[1]
let l:text = l:temp_messages[l:loop_count]

call add(l:output, {
\ 'lnum': l:num,
\ 'col': 0,
\ 'text': l:text,
\ 'type': 'W',
\ 'sub_type': 'style',
\})

let l:loop_count += 1
endfor

return l:output
endfunction

call ale#linter#Define('php', {
\ 'name': 'tlint',
\ 'executable': function('ale_linters#php#tlint#GetExecutable'),
\ 'command': function('ale_linters#php#tlint#GetCommand'),
\ 'callback': 'ale_linters#php#tlint#Handle',
\ 'project_root': function('ale_linters#php#tlint#GetProjectRoot'),
\})
30 changes: 30 additions & 0 deletions doc/ale-php.txt
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,34 @@ g:ale_php_php_executable *g:ale_php_php_executable*

This variable sets the executable used for php.


===============================================================================
tlint *ale-php-tlint*

g:ale_php_tlint_executable *g:ale_php_tlint_executable*
*b:ale_php_tlint_executable*
Type: |String|
Default: `'tlint'`

See |ale-integrations-local-executables|


g:ale_php_tlint_use_global *g:ale_php_tlint_use_global*
*b:ale_php_tlint_use_global*
Type: |Number|
Default: `get(g:, 'ale_use_global_executables', 0)`

See |ale-integrations-local-executables|


g:ale_php_tlint_options *g:ale_php_tlint_options*
*b:ale_php_tlint_options*
Type: |String|
Default: `''`

This variable can be set to pass additional options to tlint


===============================================================================
intelephense *ale-php-intelephense*

Expand All @@ -277,6 +305,7 @@ g:ale_php_intelephense_use_global *g:ale_php_intelephense_use_global*

See: |ale-integrations-local-executables|


g:ale_php_intelephense_config *g:ale_php_intelephense_config*
*b:ale_php_intelephense_config*
Type: |Dictionary|
Expand All @@ -286,5 +315,6 @@ g:ale_php_intelephense_config *g:ale_php_intelephense_config*
installation docs provided by intelephense (github.com/bmewburn/intelephense
-docs).


===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
1 change: 1 addition & 0 deletions doc/ale-supported-languages-and-tools.txt
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ Notes:
* `phpmd`
* `phpstan`
* `psalm`!!
* `tlint`
* PO
* `alex`!!
* `msgfmt`
Expand Down
1 change: 1 addition & 0 deletions doc/ale.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2805,6 +2805,7 @@ documented in additional help files.
psalm.................................|ale-php-psalm|
php-cs-fixer..........................|ale-php-php-cs-fixer|
php...................................|ale-php-php|
tlint.................................|ale-php-tlint|
intelephense..........................|ale-php-intelephense|
po......................................|ale-po-options|
write-good............................|ale-po-write-good|
Expand Down
1 change: 1 addition & 0 deletions supported-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ formatting.
* [phpmd](https://phpmd.org)
* [phpstan](https://github.com/phpstan/phpstan)
* [psalm](https://getpsalm.org) :floppy_disk:
* [tlint](https://github.com/tightenco/tlint)
* PO
* [alex](https://github.com/wooorm/alex) :floppy_disk:
* [msgfmt](https://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html)
Expand Down
34 changes: 34 additions & 0 deletions test/handler/test_tlint_handler.vader
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Before:
runtime ale_linters/php/tlint.vim

After:
call ale#linter#Reset()

Execute(The tlint handler should calculate line numbers):
AssertEqual
\ [
\ {
\ 'lnum': '5',
\ 'col': 0,
\ 'sub_type':
\ 'style',
\ 'type': 'W',
\ 'text': ['! There should be no unused imports.', 'There should be no unused imports.', '', '', '', '', '', '', '', '']
\ },
\ {
\ 'lnum': '15',
\ 'col': 0,
\ 'sub_type':
\ 'style',
\ 'type': 'W',
\ 'text': ['! There should be no method visibility in test methods.', 'There should be no method visibility in test methods.', '', '', '', '', '', '', '', '']
\ },
\ ],
\ ale_linters#php#tlint#Handle(347, [
\ "Lints for /Users/jose/Code/Tighten/tester/tests/Unit/ExampleTest.php",
\ "============",
\ "! There should be no unused imports.",
\ "5 : `use Illuminate\Foundation\Testing\RefreshDatabase;`",
\ "! There should be no method visibility in test methods.",
\ "15 : ` public function testBasicTest()`",
\ ])