diff --git a/ale_linters/apkbuild/apkbuild_lint.vim b/ale_linters/apkbuild/apkbuild_lint.vim new file mode 100644 index 00000000..285f5534 --- /dev/null +++ b/ale_linters/apkbuild/apkbuild_lint.vim @@ -0,0 +1,12 @@ +" Author: Leo +" Description: apkbuild-lint from atools linter for APKBUILDs + +call ale#Set('apkbuild_apkbuild_lint_executable', 'apkbuild-lint') + +call ale#linter#Define('apkbuild', { +\ 'name': 'apkbuild_lint', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'apkbuild_apkbuild_lint_executable')}, +\ 'command': '%e %t', +\ 'callback': 'ale#handlers#atools#Handle', +\}) diff --git a/ale_linters/apkbuild/secfixes_check.vim b/ale_linters/apkbuild/secfixes_check.vim new file mode 100644 index 00000000..c65267fd --- /dev/null +++ b/ale_linters/apkbuild/secfixes_check.vim @@ -0,0 +1,12 @@ +" Author: Leo +" Description: secfixes-check from atools linter for APKBUILDs + +call ale#Set('apkbuild_secfixes_check_executable', 'secfixes-check') + +call ale#linter#Define('apkbuild', { +\ 'name': 'secfixes_check', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'apkbuild_secfixes_check_executable')}, +\ 'command': '%e %t', +\ 'callback': 'ale#handlers#atools#Handle', +\}) diff --git a/autoload/ale/handlers/atools.vim b/autoload/ale/handlers/atools.vim new file mode 100644 index 00000000..c273fc40 --- /dev/null +++ b/autoload/ale/handlers/atools.vim @@ -0,0 +1,41 @@ +" Author: Leo +" Description: Handlers for output expected from atools + +function! ale#handlers#atools#Handle(buffer, lines) abort + " Format: SEVERITY:[TAG]:PATH:LINENUM:MSG + " Example: MC:[AL5]:./APKBUILD:12:variable set to empty string: install= + let l:pattern = '\([^:]\+\):\([^:]\+\):\([^:]\+\):\(\d\+\):\(.\+\)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + " We are expected to receive 2 characters, the first character + " can be 'S', 'I', 'M' 'T', which are respectively: + " Serious (Error) + " Important (Error) + " Minor (Warning) + " Style (Warning) + " + " The second character can be either 'C' or 'P', which are respectively: + " Certain (Error) + " Possible (Warning) + let l:severity = matchstr(l:match[1], '^.') + let l:certainty = matchstr(l:match[1], '.$') + + let l:type = 'E' + " If the tag returns 'Minor' or 'Style' or is 'Possible' + " then return a warning + + if l:severity is# 'M' || l:severity is# 'T' || l:certainty is# 'P' + let l:type = 'W' + endif + + call add(l:output, { + \ 'lnum': l:match[4] + 0, + \ 'text': l:match[5], + \ 'type': l:type, + \ 'code': matchstr(l:match[2], 'AL[0-9]*'), + \}) + endfor + + return l:output +endfunction diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim index ba11e1eb..f9ec48d7 100644 --- a/autoload/ale/linter.vim +++ b/autoload/ale/linter.vim @@ -38,6 +38,7 @@ let s:default_ale_linter_aliases = { " " NOTE: Update the g:ale_linters documentation when modifying this. let s:default_ale_linters = { +\ 'apkbuild': ['apkbuild_lint', 'secfixes_check'], \ 'csh': ['shell'], \ 'elixir': ['credo', 'dialyxir', 'dogma'], \ 'go': ['gofmt', 'golint', 'go vet'], diff --git a/doc/ale-apkbuild.txt b/doc/ale-apkbuild.txt new file mode 100644 index 00000000..05261400 --- /dev/null +++ b/doc/ale-apkbuild.txt @@ -0,0 +1,30 @@ +=============================================================================== +ALE APKBUILD Integration *ale-apkbuild-options* + + +=============================================================================== +apkbuild-lint *ale-apkbuild-apkbuild-lint* + +g:ale_apkbuild_apkbuild_lint_executable + *g:ale_apkbuild_apkbuild_lint_executable* + *b:ale_apkbuild_apkbuild_lint_executable* + + Type: |String| + Default: `'apkbuild-lint'` + + This variable can be set to change the path to apkbuild-lint + +=============================================================================== +secfixes-check *ale-apkbuild-secfixes-check* + +g:ale_apkbuild_secfixes_check_executable + *g:ale_apkbuild_secfixes_check_executable* + *b:ale_apkbuild_secfixes_check_executable* + + Type: |String| + Default: `'secfixes-check'` + + This variable can be set to change the path to secfixes-check + +=============================================================================== + 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 ce73136f..db647445 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -20,6 +20,9 @@ Notes: * `ansible-lint` * API Blueprint * `drafter` +* APKBUILD + * `apkbuild-lint` + * `secfixes-check` * AsciiDoc * `alex`!! * `languagetool`!! diff --git a/doc/ale.txt b/doc/ale.txt index 5cbc10c4..bb87ed1a 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1556,6 +1556,7 @@ g:ale_linters *g:ale_linters* following values: > { + \ 'apkbuild': ['apkbuild_lint', 'secfixes_check'], \ 'csh': ['shell'], \ 'elixir': ['credo', 'dialyxir', 'dogma'], \ 'go': ['gofmt', 'golint', 'go vet'], @@ -2599,6 +2600,9 @@ documented in additional help files. ada-language-server...................|ale-ada-language-server| ansible.................................|ale-ansible-options| ansible-lint..........................|ale-ansible-ansible-lint| + apkbuild................................|ale-apkbuild-options| + apkbuild-lint.........................|ale-apkbuild-apkbuild-lint| + secfixes-check........................|ale-apkbuild-secfixes-check| asciidoc................................|ale-asciidoc-options| write-good............................|ale-asciidoc-write-good| textlint..............................|ale-asciidoc-textlint| diff --git a/supported-tools.md b/supported-tools.md index 0e1e6b29..92ae8d83 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -29,6 +29,9 @@ formatting. * [ansible-lint](https://github.com/willthames/ansible-lint) * API Blueprint * [drafter](https://github.com/apiaryio/drafter) +* APKBUILD + * [apkbuild-lint](https://gitlab.alpinelinux.org/Leo/atools) + * [secfixes-check](https://gitlab.alpinelinux.org/Leo/atools) * AsciiDoc * [alex](https://github.com/wooorm/alex) :floppy_disk: * [languagetool](https://languagetool.org/) :floppy_disk: diff --git a/test/handler/test_atools_handler.vader b/test/handler/test_atools_handler.vader new file mode 100644 index 00000000..1bb9ca00 --- /dev/null +++ b/test/handler/test_atools_handler.vader @@ -0,0 +1,85 @@ +Before: + runtime autoload/ale/handlers/atools.vim + +After: + call ale#linter#Reset() + +Execute(The atools handler should handle basic errors or warings): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'text': 'trailing whitespace', + \ 'type': 'E', + \ 'code': 'AL8', + \ }, + \ { + \ 'lnum': 15, + \ 'text': '$pkgname should not be used in the source url', + \ 'type': 'W', + \ 'code': 'AL29', + \ }, + \ ], + \ ale#handlers#atools#Handle(bufnr(''), [ + \ 'IC:[AL8]:APKBUILD:2:trailing whitespace', + \ 'MC:[AL29]:APKBUILD:15:$pkgname should not be used in the source url', + \ ]) + +" Regardless of the severity, if the certainty is [P]ossible and not [C]ertain +" or if regardless of the Certainity the Severity is not [I]mportant or [S]erious +" then it must be a [W]arning +Execute(If we are not Certain or Importantly Serious, be a Warning): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'text': 'This violation is Serious but Possible false positive, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 4, + \ 'text': 'This violation is Important but Possible false positive, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 5, + \ 'text': 'This violation is Minor, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 6, + \ 'text': 'This violation is Style, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ ], + \ ale#handlers#atools#Handle(bufnr(''), [ + \ 'SP:[AL]:APKBUILD:3:This violation is Serious but Possible false positive, I am a Warning!', + \ 'IP:[AL]:APKBUILD:4:This violation is Important but Possible false positive, I am a Warning!', + \ 'MC:[AL]:APKBUILD:5:This violation is Minor, I am a Warning!', + \ 'TC:[AL]:APKBUILD:6:This violation is Style, I am a Warning!', + \ ]) + +Execute(We should be error if we are Certain it is Serious or Important): + AssertEqual + \ [ + \ { + \ 'lnum': 7, + \ 'text': 'This is Certainly Serious, I am an Error!', + \ 'type': 'E', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 8, + \ 'text': 'This is Certainly Important, I am an Error!', + \ 'type': 'E', + \ 'code': 'AL', + \ }, + \ ], + \ ale#handlers#atools#Handle(bufnr(''), [ + \ 'SC:[AL]:APKBUILD:7:This is Certainly Serious, I am an Error!', + \ 'IC:[AL]:APKBUILD:8:This is Certainly Important, I am an Error!', + \ ]) diff --git a/test/test_filetype_linter_defaults.vader b/test/test_filetype_linter_defaults.vader index e9980536..d4e708ec 100644 --- a/test/test_filetype_linter_defaults.vader +++ b/test/test_filetype_linter_defaults.vader @@ -70,3 +70,10 @@ Execute(The defaults for the verilog filetype should be correct): Execute(Default aliases for React should be defined): AssertEqual ['javascript', 'jsx'], ale#linter#ResolveFiletype('javascriptreact') AssertEqual ['typescript', 'tsx'], ale#linter#ResolveFiletype('typescriptreact') + +Execute(The defaults for the apkbuild filetype should be correct): + AssertEqual ['apkbuild_lint', 'secfixes_check'], GetLinterNames('apkbuild') + + let g:ale_linters_explicit = 1 + + AssertEqual [], GetLinterNames('apkbuild')