From a9d7f45924b97a5244fb626dd9ae0bf934ca1ee6 Mon Sep 17 00:00:00 2001 From: David Houston Date: Thu, 11 Nov 2021 17:34:25 -0500 Subject: Implement statix Linter and Fixer (#3969) * Add Statix for Linting Add `statix check` as a linter. Provides a simple set of definition tests additionally. Variable names specify "check" to allow for later addition of `statix fix` as a formatter once stream support is added. Signed-off-by: David Houston * Fixup Supported Tools List I didn't realise there were two separate lists of tools, so add statix to the other list. Also, remembered "S" comes after "R", and so re-ordered it. Signed-off-by: David Houston * Fix statix Test File I refactored the variables for statix to allow for writing a fixer later, and forgot to update them in the test, so update them now. Also remove a stray "i", add missing space before checks Signed-off-by: David Houston * Update Output Stream for v0.4.0 statix v0.4.0 provides a breaking change of output stream from stderr to stdout. Signed-off-by: David Houston * Add statix fix Fixer Implement statix fix as a fixer for simple Nix antipatterns. Signed-off-by: David Houston * Fix statix Fixer Tests Fix the statix fixer tests by removing the unnecessary 'read_temporary_file' value from the command, since it simply uses the default value. Signed-off-by: David Houston * Add statix Handler Test Add a test for the statix handler per @hsanson's request. Signed-off-by: David Houston * Fix to run only on stdin for linting Signed-off-by: David Houston --- ale_linters/nix/statix.vim | 18 +++++++++++ autoload/ale/fix/registry.vim | 5 +++ autoload/ale/fixers/statix.vim | 17 ++++++++++ autoload/ale/handlers/statix.vim | 24 ++++++++++++++ doc/ale-nix.txt | 53 ++++++++++++++++++++++++++----- doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + test/fixers/test_statix_fixer.vader | 18 +++++++++++ test/handler/test_statix_handler.vader | 16 ++++++++++ test/linter/test_nix_statix.vader | 19 +++++++++++ 11 files changed, 165 insertions(+), 8 deletions(-) create mode 100644 ale_linters/nix/statix.vim create mode 100644 autoload/ale/fixers/statix.vim create mode 100644 autoload/ale/handlers/statix.vim create mode 100644 test/fixers/test_statix_fixer.vader create mode 100644 test/handler/test_statix_handler.vader create mode 100644 test/linter/test_nix_statix.vader diff --git a/ale_linters/nix/statix.vim b/ale_linters/nix/statix.vim new file mode 100644 index 00000000..a90a68a6 --- /dev/null +++ b/ale_linters/nix/statix.vim @@ -0,0 +1,18 @@ +scriptencoding utf-8 +" Author: David Houston +" Description: statix analysis and suggestions for Nix files + +call ale#Set('nix_statix_check_executable', 'statix') +call ale#Set('nix_statix_check_options', '') + +function! ale_linters#nix#statix#GetCommand(buffer) abort + return '%e check -o errfmt --stdin' + \ . ale#Pad(ale#Var(a:buffer, 'nix_statix_check_options')) +endfunction + +call ale#linter#Define('nix', { +\ 'name': 'statix', +\ 'executable': {b -> ale#Var(b, 'nix_statix_check_executable')}, +\ 'command': function('ale_linters#nix#statix#GetCommand'), +\ 'callback': 'ale#handlers#statix#Handle', +\}) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index eb7d7f53..c80d2271 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -191,6 +191,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['ruby'], \ 'description': 'Fix ruby files with standardrb --fix', \ }, +\ 'statix': { +\ 'function': 'ale#fixers#statix#Fix', +\ 'suggested_filetypes': ['nix'], +\ 'description': 'Fix common Nix antipatterns with statix fix', +\ }, \ 'stylelint': { \ 'function': 'ale#fixers#stylelint#Fix', \ 'suggested_filetypes': ['css', 'sass', 'scss', 'sugarss', 'stylus'], diff --git a/autoload/ale/fixers/statix.vim b/autoload/ale/fixers/statix.vim new file mode 100644 index 00000000..5991c925 --- /dev/null +++ b/autoload/ale/fixers/statix.vim @@ -0,0 +1,17 @@ +" Author: David Houston +" Description: Provide statix fix as a fixer for simple Nix antipatterns. + +call ale#Set('nix_statix_fix_executable', 'statix') +call ale#Set('nix_statix_fix_options', '') + +function! ale#fixers#statix#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'nix_statix_fix_executable') + let l:options = ale#Var(a:buffer, 'nix_statix_fix_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ale#Pad('fix') + \ . ale#Pad('--stdin') + \ . ale#Pad(l:options), + \} +endfunction diff --git a/autoload/ale/handlers/statix.vim b/autoload/ale/handlers/statix.vim new file mode 100644 index 00000000..eeef4107 --- /dev/null +++ b/autoload/ale/handlers/statix.vim @@ -0,0 +1,24 @@ +scriptencoding utf-8 +" Author: David Houston +" Description: This file defines a handler function for statix's errorformat +" output. + +function! ale#handlers#statix#Handle(buffer, lines) abort + " Look for lines like the following. + " + " flake.nix>46:13:W:3:This assignment is better written with `inherit` + let l:pattern = '\v^.*\>(\d+):(\d+):([A-Z]):(\d+):(.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'type': l:match[3], + \ 'code': l:match[4], + \ 'text': l:match[5], + \}) + endfor + + return l:output +endfunction diff --git a/doc/ale-nix.txt b/doc/ale-nix.txt index c38b93db..1df7caff 100644 --- a/doc/ale-nix.txt +++ b/doc/ale-nix.txt @@ -7,24 +7,24 @@ nixfmt *ale-nix-nixfmt* g:ale_nix_nixfmt_executable *g:ale_nix_nixfmt_executable* *b:ale_nix_nixfmt_executable* - Type: String - Default: 'nixfmt' + Type: |String| + Default: `'nixfmt'` This variable sets the executable used for nixfmt. g:ale_nix_nixfmt_options *g:ale_nix_nixfmt_options* *b:ale_nix_nixfmt_options* - Type: String - Default: '' + Type: |String| + Default: `''` This variable can be set to pass additional options to the nixfmt fixer. =============================================================================== -nixpkgs-fmt *ale-nix-nixpkgs-fmt* +nixpkgs-fmt *ale-nix-nixpkgs-fmt* -g:ale_nix_nixpkgsfmt_executable *g:ale_nix_nixpkgsfmt_executable* - *b:ale_nix_nixpkgsfmt_executable* +g:ale_nix_nixpkgsfmt_executable *g:ale_nix_nixpkgsfmt_executable* + *b:ale_nix_nixpkgsfmt_executable* Type: |String| Default: `'nixpkgs-fmt'` @@ -35,7 +35,44 @@ g:ale_nix_nixpkgsfmt_options *g:ale_nix_nixpkgsfmt_options* Type: |String| Default: `''` - This variable can be set to pass additional options to the nixpkgs-fmt fixer. + This variable can be set to pass additional options to the nixpkgs-fmt + fixer. + + +=============================================================================== +statix *ale-nix-statix* + +g:ale_nix_statix_check_executable *g:ale_nix_statix_check_executable* + *b:ale_nix_statix_check_executable* + Type: |String| + Default: `'statix'` + + This variable sets the executable used for statix when running it as a + linter. + +g:ale_nix_statix_check_options *g:ale_nix_statix_check_options* + *b:ale_nix_statix_check_options* + Type: |String| + Default: `''` + + This variable can be used to pass additional options to statix when running + it as a linter. + +g:ale_nix_statix_fix_executable *g:ale_nix_fix_check_executable* + *b:ale_nix_fix_check_executable* + Type: |String| + Default: `'statix'` + + This variable sets the executable used for statix when running it as a + fixer. + +g:ale_nix_statix_fix_options *g:ale_nix_statix_fix_options* + *b:ale_nix_statix_fix_options* + Type: |String| + Default: `''` + + This variable can be used to pass additional options to statix when running + it as a fixer. =============================================================================== diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 0e1da319..bd23dade 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -340,6 +340,7 @@ Notes: * `nixfmt` * `nixpkgs-fmt` * `rnix-lsp` + * `statix` * nroff * `alex`!! * `proselint` diff --git a/doc/ale.txt b/doc/ale.txt index 71da263a..752af42f 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2879,6 +2879,7 @@ documented in additional help files. nix.....................................|ale-nix-options| nixfmt................................|ale-nix-nixfmt| nixpkgs-fmt...........................|ale-nix-nixpkgs-fmt| + statix................................|ale-nix-statix| nroff...................................|ale-nroff-options| write-good............................|ale-nroff-write-good| objc....................................|ale-objc-options| diff --git a/supported-tools.md b/supported-tools.md index ab02b006..a0da372c 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -349,6 +349,7 @@ formatting. * [nixfmt](https://github.com/serokell/nixfmt) * [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt) * [rnix-lsp](https://github.com/nix-community/rnix-lsp) + * [statix](https://github.com/nerdypepper/statix) * nroff * [alex](https://github.com/wooorm/alex) :floppy_disk: * [proselint](http://proselint.com/) diff --git a/test/fixers/test_statix_fixer.vader b/test/fixers/test_statix_fixer.vader new file mode 100644 index 00000000..c55365a6 --- /dev/null +++ b/test/fixers/test_statix_fixer.vader @@ -0,0 +1,18 @@ +Before: + call ale#assert#SetUpFixerTest('nix', 'statix') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The callback should return the correct default values): + AssertFixer { 'command': ale#Escape('statix') . ' fix --stdin' } + +Execute(The callback should include a custom runtime): + let g:ale_nix_statix_fix_executable = 'foo/bar' + + AssertFixer { 'command': ale#Escape('foo/bar') . ' fix --stdin' } + +Execute(The callback should include custom options): + let g:ale_nix_statix_fix_options = '--foobar' + + AssertFixer { 'command': ale#Escape('statix') . ' fix --stdin --foobar' } diff --git a/test/handler/test_statix_handler.vader b/test/handler/test_statix_handler.vader new file mode 100644 index 00000000..f2a105ee --- /dev/null +++ b/test/handler/test_statix_handler.vader @@ -0,0 +1,16 @@ +Execute(The statix handler should handle statix output): + call ale#test#SetFilename('flake.nix') + + AssertEqual + \ [ + \ { + \ 'lnum': 46, + \ 'type': 'W', + \ 'col': 13, + \ 'code': '3', + \ 'text': 'This assignment is better written with `inherit`' + \ }, + \ ], + \ ale#handlers#statix#Handle(bufnr(''), + \ '>46:13:W:3:This assignment is better written with `inherit`' + \) diff --git a/test/linter/test_nix_statix.vader b/test/linter/test_nix_statix.vader new file mode 100644 index 00000000..8ee4c027 --- /dev/null +++ b/test/linter/test_nix_statix.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('nix', 'statix') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The statix command should be correct): + AssertLinter 'statix', ale#Escape('statix') . ' check -o errfmt --stdin' + +Execute(Additional statix options should be configurable): + let g:ale_nix_statix_check_options = '--foobar' + + AssertLinter 'statix', + \ ale#Escape('statix') . ' check -o errfmt --stdin --foobar' + +Execute(The statix command should be configurable): + let g:ale_nix_statix_check_executable = 'foo/bar' + + AssertLinter 'foo/bar', ale#Escape('foo/bar') . ' check -o errfmt --stdin' -- cgit v1.2.3