From 93100159a2ee71fea8853dcd45ec48c8222516fe Mon Sep 17 00:00:00 2001 From: Carl Smedstad Date: Thu, 13 Apr 2023 01:51:52 +0200 Subject: Add support for Bicep when installed as a plugin to Azure CLI (#4496) * Add support for Bicep when installed as a plugin to Azure CLI The compiler for Microsoft's DSL Bicep can be installed both independently and as a plugin to Azure CLI. The latter is probably how most people install it. The program output is the same but Azure CLI wraps the arguments and has a slightly different interface, hence I opted to copy the old linter and modify it to match the plugin arguments. * Fix bicep/az_bicep tests, arguments and parsing * Actually test the ale_linters#bicep#az_bicep#Handle function in the test that should test that function, not ale_linters#bicep#bicep#Handle. * Use the same method as in bicep/bicep for discarding output file, i.e. by specifying --outfile to a null file. * Fix parsing of occasionally occurring leading error type (such as 'ERROR: '). * Correct option defaults for bicep & az_bicep specified in documentation --- ale_linters/bicep/az_bicep.vim | 69 ++++++++++++++++++++++++++ ale_linters/bicep/bicep.vim | 15 +++--- doc/ale-bicep.txt | 21 +++++++- doc/ale.txt | 1 + test/handler/test_bicep_az_bicep_handler.vader | 41 +++++++++++++++ test/handler/test_bicep_bicep_handler.vader | 4 +- test/linter/test_bicep_az_bicep.vader | 21 ++++++++ 7 files changed, 163 insertions(+), 9 deletions(-) create mode 100644 ale_linters/bicep/az_bicep.vim create mode 100644 test/handler/test_bicep_az_bicep_handler.vader create mode 100644 test/linter/test_bicep_az_bicep.vader diff --git a/ale_linters/bicep/az_bicep.vim b/ale_linters/bicep/az_bicep.vim new file mode 100644 index 00000000..f487ae0f --- /dev/null +++ b/ale_linters/bicep/az_bicep.vim @@ -0,0 +1,69 @@ +" Author: Carl Smedstad +" Description: az_bicep for bicep files + +let g:ale_bicep_az_bicep_executable = +\ get(g:, 'ale_bicep_az_bicep_executable', 'az') + +let g:ale_bicep_az_bicep_options = +\ get(g:, 'ale_bicep_az_bicep_options', '') + +function! ale_linters#bicep#az_bicep#Executable(buffer) abort + return ale#Var(a:buffer, 'bicep_az_bicep_executable') +endfunction + +function! ale_linters#bicep#az_bicep#Command(buffer) abort + let l:executable = ale_linters#bicep#az_bicep#Executable(a:buffer) + let l:options = ale#Var(a:buffer, 'bicep_az_bicep_options') + + if has('win32') + let l:nullfile = 'NUL' + else + let l:nullfile = '/dev/null' + endif + + return ale#Escape(l:executable) + \ . ' bicep build --outfile ' + \ . l:nullfile + \ . ' --file ' + \ . '%s ' + \ . l:options +endfunction + +function! ale_linters#bicep#az_bicep#Handle(buffer, lines) abort + let l:pattern = '\v^([A-Z]+)?(:\s)?(.*)\((\d+),(\d+)\)\s:\s([a-zA-Z]*)\s([-a-zA-Z0-9]*):\s(.*)' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + if l:match[1] is# 'ERROR' + let l:type = 'E' + elseif l:match[1] is# 'WARNING' + let l:type = 'W' + elseif l:match[6] is# 'Error' + let l:type = 'E' + elseif l:match[6] is# 'Warning' + let l:type = 'W' + else + let l:type = 'I' + endif + + call add(l:output, { + \ 'filename': l:match[3], + \ 'lnum': l:match[4] + 0, + \ 'col': l:match[5] + 0, + \ 'type': l:type, + \ 'code': l:match[7], + \ 'text': l:match[8], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('bicep', { +\ 'name': 'az_bicep', +\ 'executable': function('ale_linters#bicep#az_bicep#Executable'), +\ 'command': function('ale_linters#bicep#az_bicep#Command'), +\ 'callback': 'ale_linters#bicep#az_bicep#Handle', +\ 'output_stream': 'stderr', +\ 'lint_file': 1, +\}) diff --git a/ale_linters/bicep/bicep.vim b/ale_linters/bicep/bicep.vim index 91cc1986..a5f0d7c6 100644 --- a/ale_linters/bicep/bicep.vim +++ b/ale_linters/bicep/bicep.vim @@ -30,24 +30,25 @@ function! ale_linters#bicep#bicep#Command(buffer) abort endfunction function! ale_linters#bicep#bicep#Handle(buffer, lines) abort - let l:pattern = '\v^.*\((\d+),(\d+)\)\s:\s([a-zA-Z]*)\s([-a-zA-Z0-9]*):\s(.*)' + let l:pattern = '\v^(.*)\((\d+),(\d+)\)\s:\s([a-zA-Z]*)\s([-a-zA-Z0-9]*):\s(.*)' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) - if l:match[3] is# 'Error' + if l:match[4] is# 'Error' let l:type = 'E' - elseif l:match[3] is# 'Warning' + elseif l:match[4] is# 'Warning' let l:type = 'W' else let l:type = 'I' endif call add(l:output, { - \ 'lnum': l:match[1] + 0, - \ 'col': l:match[2] + 0, + \ 'filename': l:match[1], + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, \ 'type': l:type, - \ 'code': l:match[4], - \ 'text': l:match[5], + \ 'code': l:match[5], + \ 'text': l:match[6], \}) endfor diff --git a/doc/ale-bicep.txt b/doc/ale-bicep.txt index d26d67bc..a5ab645d 100644 --- a/doc/ale-bicep.txt +++ b/doc/ale-bicep.txt @@ -16,9 +16,28 @@ g:ale_bicep_bicep_executable *g:ale_bicep_bicep_executable* g:ale_bicep_bicep_options *g:ale_bicep_bicep_options* *b:ale_bicep_bicep_options* Type: |String| - Default: `'build --outfile /dev/null'` + Default: `''` This variable can be set to pass additional options to bicep. + +=============================================================================== +az_bicep *ale-bicep-az_bicep* + +g:ale_bicep_az_bicep_executable *g:ale_bicep_az_bicep_executable* + *b:ale_bicep_az_bicep_executable* + Type: |String| + Default: `'az'` + + This variable can be set to change the path to az_bicep. + + +g:ale_bicep_az_bicep_options *g:ale_bicep_az_bicep_options* + *b:ale_bicep_az_bicep_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to az_bicep. + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index f55e73bc..ffdde04c 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2858,6 +2858,7 @@ documented in additional help files. bibclean..............................|ale-bib-bibclean| bicep...................................|ale-bicep-options| bicep.................................|ale-bicep-bicep| + az_bicep..............................|ale-bicep-az_bicep| bitbake.................................|ale-bitbake-options| oelint-adv............................|ale-bitbake-oelint_adv| c.......................................|ale-c-options| diff --git a/test/handler/test_bicep_az_bicep_handler.vader b/test/handler/test_bicep_az_bicep_handler.vader new file mode 100644 index 00000000..5205b83b --- /dev/null +++ b/test/handler/test_bicep_az_bicep_handler.vader @@ -0,0 +1,41 @@ +Before: + runtime ale_linters/bicep/az_bicep.vim + +After: + Restore + + call ale#linter#Reset() + +Execute(The az_bicep handler should handle basic warnings): + AssertEqual + \ [ + \ { + \ 'filename': '/tmp/nvimhxqs5D/1/dns.bicep', + \ 'lnum': 7, + \ 'col': 10, + \ 'type': 'W', + \ 'code': 'no-unused-existing-resources', + \ 'text': 'Existing resource "asdasd" is declared but never used. [https://aka.ms/bicep/linter/no-unused-existing-resources]', + \ }, + \ { + \ 'filename': '/tmp/nvimhxqs5D/1/dns.bicep', + \ 'lnum': 106, + \ 'col': 6, + \ 'type': 'E', + \ 'code': 'BCP019', + \ 'text': 'Expected a new line character at this location.', + \ }, + \ { + \ 'filename': '/tmp/cluster.bicep', + \ 'lnum': 25, + \ 'col': 30, + \ 'type': 'E', + \ 'code': 'BCP334', + \ 'text': 'The provided value has no configured minimum length and may be too short to assign to a target with a configured minimum length of 1.', + \ }, + \ ], + \ ale_linters#bicep#az_bicep#Handle(1, [ + \ '/tmp/nvimhxqs5D/1/dns.bicep(7,10) : Warning no-unused-existing-resources: Existing resource "asdasd" is declared but never used. [https://aka.ms/bicep/linter/no-unused-existing-resources]', + \ '/tmp/nvimhxqs5D/1/dns.bicep(106,6) : Error BCP019: Expected a new line character at this location.', + \ 'ERROR: /tmp/cluster.bicep(25,30) : Warning BCP334: The provided value has no configured minimum length and may be too short to assign to a target with a configured minimum length of 1.', + \ ]) diff --git a/test/handler/test_bicep_bicep_handler.vader b/test/handler/test_bicep_bicep_handler.vader index d105cae5..b91c2551 100644 --- a/test/handler/test_bicep_bicep_handler.vader +++ b/test/handler/test_bicep_bicep_handler.vader @@ -6,10 +6,11 @@ After: call ale#linter#Reset() -Execute(The cmake_lint handler should handle basic warnings): +Execute(The bicep handler should handle basic warnings): AssertEqual \ [ \ { + \ 'filename': '/tmp/nvimhxqs5D/1/dns.bicep', \ 'lnum': 7, \ 'col': 10, \ 'type': 'W', @@ -17,6 +18,7 @@ Execute(The cmake_lint handler should handle basic warnings): \ 'text': 'Existing resource "asdasd" is declared but never used. [https://aka.ms/bicep/linter/no-unused-existing-resources]', \ }, \ { + \ 'filename': '/tmp/nvimhxqs5D/1/dns.bicep', \ 'lnum': 106, \ 'col': 6, \ 'type': 'E', diff --git a/test/linter/test_bicep_az_bicep.vader b/test/linter/test_bicep_az_bicep.vader new file mode 100644 index 00000000..b5dee48e --- /dev/null +++ b/test/linter/test_bicep_az_bicep.vader @@ -0,0 +1,21 @@ +Before: + call ale#assert#SetUpLinterTest('bicep', 'az_bicep') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + if has('win32') + AssertLinter 'az', ale#Escape('az') . ' bicep build --outfile NUL --file %s ' + else + AssertLinter 'az', ale#Escape('az') . ' bicep build --outfile /dev/null --file %s ' + endif + +Execute(The executable should be configurable): + let g:ale_bicep_az_bicep_executable = 'foobar' + + if has('win32') + AssertLinter 'foobar', ale#Escape('foobar') . ' bicep build --outfile NUL --file %s ' + else + AssertLinter 'foobar', ale#Escape('foobar') . ' bicep build --outfile /dev/null --file %s ' + endif -- cgit v1.2.3