From d12ad1ca2c80b2ae42f62d4a2c05914e039cce12 Mon Sep 17 00:00:00 2001 From: Jose Soto Date: Fri, 13 Sep 2019 16:06:55 -0400 Subject: [PATCH 1/7] Initial Tlint linter implementation --- ale_linters/php/tlint.vim | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 ale_linters/php/tlint.vim diff --git a/ale_linters/php/tlint.vim b/ale_linters/php/tlint.vim new file mode 100644 index 0000000000..0fffca77dd --- /dev/null +++ b/ale_linters/php/tlint.vim @@ -0,0 +1,50 @@ +" Author: Jose Soto +" +" Description: Tighten Opinionated Linting + +let g:ale_php_tlint_executable = get(g:, 'ale_php_tlint_executable', 'tlint') + +function! ale_linters#php#tlint#GetCommand(buffer) abort + return '%e 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:pattern = '^\(\d\+\) \:' + let l:loopCount = 0 + let l:messagePattern = '^\! \(.*\)' + let l:output = [] + let l:tempMessages = [] + + for l:message in ale#util#GetMatches(a:lines, l:messagePattern) + call add(l:tempMessages, l:message) + endfor + + let l:loopCount = 0 + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:num = l:match[1] + let l:text = l:tempMessages[l:loopCount] + + call add(l:output, { + \ 'lnum': l:num, + \ 'col': 0, + \ 'text': l:text, + \ 'type': 'W', + \ 'sub_type': 'style', + \}) + + let l:loopCount += 1 + endfor + return l:output +endfunction + +call ale#linter#Define('php', { +\ 'name': 'tlint', +\ 'executable': {b -> ale#Var(b, 'php_tlint_executable')}, +\ 'command': function('ale_linters#php#tlint#GetCommand'), +\ 'callback': 'ale_linters#php#tlint#Handle', +\}) From 312b6e108f7307e0b9a225e9a94b06e5b3d7050c Mon Sep 17 00:00:00 2001 From: Jose Soto Date: Fri, 20 Sep 2019 15:57:07 -0400 Subject: [PATCH 2/7] Improved tlint.vim file and some document updates. --- ale_linters/php/tlint.vim | 36 ++++++++++++++++++++--- doc/ale-php.txt | 26 ++++++++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/ale_linters/php/tlint.vim b/ale_linters/php/tlint.vim index 0fffca77dd..0e472e416b 100644 --- a/ale_linters/php/tlint.vim +++ b/ale_linters/php/tlint.vim @@ -1,11 +1,38 @@ " Author: Jose Soto " " Description: Tighten Opinionated Linting +" Website: https://github.com/tightenco/tlint -let g:ale_php_tlint_executable = get(g:, 'ale_php_tlint_executable', '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 - return '%e lint %s' + 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 @@ -14,10 +41,10 @@ function! ale_linters#php#tlint#Handle(buffer, lines) abort " ! There should be 1 space around `.` concatenations, and additional lines should always start with a `.` " 22 : ` $something = 'a'.'name';` " - let l:pattern = '^\(\d\+\) \:' let l:loopCount = 0 let l:messagePattern = '^\! \(.*\)' let l:output = [] + let l:pattern = '^\(\d\+\) \:' let l:tempMessages = [] for l:message in ale#util#GetMatches(a:lines, l:messagePattern) @@ -44,7 +71,8 @@ endfunction call ale#linter#Define('php', { \ 'name': 'tlint', -\ 'executable': {b -> ale#Var(b, 'php_tlint_executable')}, +\ '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'), \}) diff --git a/doc/ale-php.txt b/doc/ale-php.txt index d41fb50d9a..0af4194866 100644 --- a/doc/ale-php.txt +++ b/doc/ale-php.txt @@ -223,5 +223,31 @@ 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 + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 98c6f354c0..7ca1a372c9 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -318,6 +318,7 @@ Notes: * `phpmd` * `phpstan` * `psalm`!! + * `tlint` * PO * `alex`!! * `msgfmt` diff --git a/doc/ale.txt b/doc/ale.txt index 5a12392122..b05384a254 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2282,6 +2282,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| po......................................|ale-po-options| write-good............................|ale-po-write-good| pod.....................................|ale-pod-options| diff --git a/supported-tools.md b/supported-tools.md index 6cbc2f2c4d..861864c644 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -327,6 +327,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) From 48411853c8ebb1c43d5fad74c480326c7f5dd8d9 Mon Sep 17 00:00:00 2001 From: Jose Soto Date: Fri, 11 Oct 2019 16:19:57 -0400 Subject: [PATCH 3/7] Adds vader test for tlint --- ale_linters/php/tlint.vim | 2 +- test/handler/test_tlint_handler.vader | 34 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test/handler/test_tlint_handler.vader diff --git a/ale_linters/php/tlint.vim b/ale_linters/php/tlint.vim index 0e472e416b..92e3574fd4 100644 --- a/ale_linters/php/tlint.vim +++ b/ale_linters/php/tlint.vim @@ -1,6 +1,6 @@ " Author: Jose Soto " -" Description: Tighten Opinionated Linting +" Description: Tighten Opinionated PHP Linting " Website: https://github.com/tightenco/tlint call ale#Set('php_tlint_executable', 'tlint') diff --git a/test/handler/test_tlint_handler.vader b/test/handler/test_tlint_handler.vader new file mode 100644 index 0000000000..e146346c67 --- /dev/null +++ b/test/handler/test_tlint_handler.vader @@ -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()`", + \ ]) From 2c70567b1145017648ad62c2bab3d37cd4f51e7a Mon Sep 17 00:00:00 2001 From: Jose Soto Date: Fri, 13 Sep 2019 16:06:55 -0400 Subject: [PATCH 4/7] Initial Tlint linter implementation --- ale_linters/php/tlint.vim | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 ale_linters/php/tlint.vim diff --git a/ale_linters/php/tlint.vim b/ale_linters/php/tlint.vim new file mode 100644 index 0000000000..0fffca77dd --- /dev/null +++ b/ale_linters/php/tlint.vim @@ -0,0 +1,50 @@ +" Author: Jose Soto +" +" Description: Tighten Opinionated Linting + +let g:ale_php_tlint_executable = get(g:, 'ale_php_tlint_executable', 'tlint') + +function! ale_linters#php#tlint#GetCommand(buffer) abort + return '%e 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:pattern = '^\(\d\+\) \:' + let l:loopCount = 0 + let l:messagePattern = '^\! \(.*\)' + let l:output = [] + let l:tempMessages = [] + + for l:message in ale#util#GetMatches(a:lines, l:messagePattern) + call add(l:tempMessages, l:message) + endfor + + let l:loopCount = 0 + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:num = l:match[1] + let l:text = l:tempMessages[l:loopCount] + + call add(l:output, { + \ 'lnum': l:num, + \ 'col': 0, + \ 'text': l:text, + \ 'type': 'W', + \ 'sub_type': 'style', + \}) + + let l:loopCount += 1 + endfor + return l:output +endfunction + +call ale#linter#Define('php', { +\ 'name': 'tlint', +\ 'executable': {b -> ale#Var(b, 'php_tlint_executable')}, +\ 'command': function('ale_linters#php#tlint#GetCommand'), +\ 'callback': 'ale_linters#php#tlint#Handle', +\}) From 0484d9b00d063587bad57f61dd754ee295484432 Mon Sep 17 00:00:00 2001 From: Jose Soto Date: Sat, 15 Aug 2020 00:24:52 -0700 Subject: [PATCH 5/7] PR Review Fixes --- ale_linters/php/tlint.vim | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ale_linters/php/tlint.vim b/ale_linters/php/tlint.vim index 92e3574fd4..71b2f21f41 100644 --- a/ale_linters/php/tlint.vim +++ b/ale_linters/php/tlint.vim @@ -10,7 +10,7 @@ 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)) + if !empty(l:composer_path) return fnamemodify(l:composer_path, ':h') endif @@ -41,20 +41,20 @@ function! ale_linters#php#tlint#Handle(buffer, lines) abort " ! There should be 1 space around `.` concatenations, and additional lines should always start with a `.` " 22 : ` $something = 'a'.'name';` " - let l:loopCount = 0 - let l:messagePattern = '^\! \(.*\)' + let l:loop_count = 0 + let l:messages_pattern = '^\! \(.*\)' let l:output = [] let l:pattern = '^\(\d\+\) \:' - let l:tempMessages = [] + let l:temp_messages = [] - for l:message in ale#util#GetMatches(a:lines, l:messagePattern) - call add(l:tempMessages, l:message) + for l:message in ale#util#GetMatches(a:lines, l:messages_pattern) + call add(l:temp_messages, l:message) endfor - let l:loopCount = 0 + 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:tempMessages[l:loopCount] + let l:text = l:temp_messages[l:loop_count] call add(l:output, { \ 'lnum': l:num, @@ -64,7 +64,7 @@ function! ale_linters#php#tlint#Handle(buffer, lines) abort \ 'sub_type': 'style', \}) - let l:loopCount += 1 + let l:loop_count += 1 endfor return l:output endfunction From 1fc5c5425f6f7c245de0b0bdec0cbb3f38439b6c Mon Sep 17 00:00:00 2001 From: Jose Soto Date: Sat, 15 Aug 2020 00:35:46 -0700 Subject: [PATCH 6/7] Travis Fixes --- ale_linters/php/tlint.vim | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ale_linters/php/tlint.vim b/ale_linters/php/tlint.vim index 71b2f21f41..68376e13a1 100644 --- a/ale_linters/php/tlint.vim +++ b/ale_linters/php/tlint.vim @@ -47,11 +47,12 @@ function! ale_linters#php#tlint#Handle(buffer, lines) abort 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 + 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] @@ -63,10 +64,12 @@ function! ale_linters#php#tlint#Handle(buffer, lines) abort \ 'type': 'W', \ 'sub_type': 'style', \}) - - let l:loop_count += 1 + + let l:loop_count += 1 endfor + return l:output + endfunction call ale#linter#Define('php', { From 996530e4c7851d419c905565dbd5b990231d3121 Mon Sep 17 00:00:00 2001 From: Jose Soto Date: Sat, 15 Aug 2020 00:44:50 -0700 Subject: [PATCH 7/7] More Travis Cleanup --- ale_linters/php/tlint.vim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ale_linters/php/tlint.vim b/ale_linters/php/tlint.vim index 68376e13a1..6bba8defd6 100644 --- a/ale_linters/php/tlint.vim +++ b/ale_linters/php/tlint.vim @@ -64,12 +64,11 @@ function! ale_linters#php#tlint#Handle(buffer, lines) abort \ 'type': 'W', \ 'sub_type': 'style', \}) - + let l:loop_count += 1 endfor return l:output - endfunction call ale#linter#Define('php', {