add rego support (#4199)

* add opa fmt fixer for rego files

* add opa linter

* add basic tests for linter and fixer

* add cspell to the docs
This commit is contained in:
Reza J. Bavaghoush 2022-05-16 14:14:11 +02:00 committed by GitHub
parent 5479b58660
commit 75d2413425
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 191 additions and 0 deletions

View File

@ -0,0 +1,4 @@
scriptencoding utf-8
" Description: cspell support for rego files.
call ale#handlers#cspell#DefineLinter('rego')

View File

@ -0,0 +1,56 @@
" Description: opa check for rego files
call ale#Set('rego_opacheck_executable', 'opa')
call ale#Set('rego_opacheck_options', '')
function! ale_linters#rego#opacheck#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'rego_opacheck_executable')
endfunction
function! ale_linters#rego#opacheck#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'rego_opacheck_options')
return ale#Escape(ale_linters#rego#opacheck#GetExecutable(a:buffer))
\ . ' check %s --format json '
\ . (!empty(l:options) ? ' ' . l:options : '')
endfunction
function! ale_linters#rego#opacheck#Handle(buffer, lines) abort
let l:output = []
let l:errors = ale#util#FuzzyJSONDecode(a:lines, {'errors': []})
let l:dir = expand('#' . a:buffer . ':p:h')
let l:file = expand('#' . a:buffer . ':p')
for l:error in l:errors['errors']
if has_key(l:error, 'location')
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:error['location']['file']),
\ 'lnum': l:error['location']['row'],
\ 'col': l:error['location']['col'],
\ 'text': l:error['message'],
\ 'code': l:error['code'],
\ 'type': 'E',
\})
else
call add(l:output, {
\ 'filename': l:file,
\ 'lnum': 0,
\ 'col': 0,
\ 'text': l:error['message'],
\ 'code': l:error['code'],
\ 'type': 'E',
\})
endif
endfor
return l:output
endfunction
call ale#linter#Define('rego', {
\ 'name': 'opacheck',
\ 'output_stream': 'both',
\ 'executable': function('ale_linters#rego#opacheck#GetExecutable'),
\ 'command': function('ale_linters#rego#opacheck#GetCommand'),
\ 'callback': 'ale_linters#rego#opacheck#Handle',
\})

View File

@ -526,6 +526,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['pascal'],
\ 'description': 'Fix Pascal files with ptop.',
\ },
\ 'opafmt': {
\ 'function': 'ale#fixers#opafmt#Fix',
\ 'suggested_filetypes': ['rego'],
\ 'description': 'Fix rego files with opa fmt.',
\ },
\ 'vfmt': {
\ 'function': 'ale#fixers#vfmt#Fix',
\ 'suggested_filetypes': ['v'],

View File

@ -0,0 +1,15 @@
" Description: Fixer for rego files
call ale#Set('opa_fmt_executable', 'opa')
call ale#Set('opa_fmt_options', '')
function! ale#fixers#opafmt#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'opa_fmt_executable')
let l:options = ale#Var(a:buffer, 'opa_fmt_options')
return {
\ 'command': ale#Escape(l:executable)
\ . ' fmt'
\ . (empty(l:options) ? '' : ' ' . l:options)
\}
endfunction

50
doc/ale-rego.txt Normal file
View File

@ -0,0 +1,50 @@
===============================================================================
ALE Rego Integration *ale-rego-options*
===============================================================================
cspell *ale-rego-cspell*
See |ale-cspell-options|
===============================================================================
opacheck *ale-rego-opa-check*
g:ale_rego_opacheck_executable *g:rego_opacheck_executable*
*b:rego_opacheck_executable*
Type: |String|
Default: `'opa'`
This variable can be changed to use a different executable for opa.
g:rego_opacheck_options *g:rego_opacheck_options*
*b:rego_opacheck_options*
Type: |String|
Default: `''`
This variable can be changed to pass custom CLI flags to opa check.
===============================================================================
opafmt *ale-rego-opa-fmt-fixer*
g:ale_opa_fmt_executable *g:ale_opa_fmt_executable*
*b:ale_opa_fmt_executable*
Type: |String|
Default: `'opa'`
This variable can be changed to use a different executable for opa.
g:ale_opa_fmt_options *g:ale_opa_fmt_options*
*b:ale_opa_fmt_options*
Type: |String|
Default: `''`
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@ -489,6 +489,10 @@ Notes:
* `ols`
* `reason-language-server`
* `refmt`
* Rego
* `cspell`
* `opacheck`
* `opafmt`
* reStructuredText
* `alex`
* `cspell`

View File

@ -3128,6 +3128,10 @@ documented in additional help files.
ols...................................|ale-reasonml-ols|
reason-language-server................|ale-reasonml-language-server|
refmt.................................|ale-reasonml-refmt|
rego....................................|ale-rego-options|
cspell................................|ale-rego-cspell|
opacheck..............................|ale-rego-opa-check|
opafmt................................|ale-rego-opa-fmt-fixer|
restructuredtext........................|ale-restructuredtext-options|
cspell................................|ale-restructuredtext-cspell|
textlint..............................|ale-restructuredtext-textlint|

View File

@ -498,6 +498,10 @@ formatting.
* [ols](https://github.com/freebroccolo/ocaml-language-server)
* [reason-language-server](https://github.com/jaredly/reason-language-server)
* [refmt](https://github.com/reasonml/reason-cli)
* Rego
* [cspell](https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell)
* [opacheck](https://www.openpolicyagent.org/docs/latest/cli/#opa-check)
* [opafmt](https://www.openpolicyagent.org/docs/latest/cli/#opa-fmt)
* reStructuredText
* [alex](https://github.com/get-alex/alex)
* [cspell](https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell)

View File

@ -0,0 +1,33 @@
Before:
Save g:ale_opa_fmt_executable
Save g:ale_opa_fmt_options
" Use an invalid global executable, so we don't match it.
let g:ale_opa_fmt_executable = 'xxxinvalid'
let g:ale_opa_fmt_options = ''
call ale#test#SetDirectory('/testplugin/test/fixers')
After:
Restore
call ale#test#RestoreDirectory()
Execute(The opa fmt callback should return the correct default values):
AssertEqual
\ {
\ 'command': ale#Escape('xxxinvalid') . ' fmt',
\ },
\ ale#fixers#opafmt#Fix(bufnr(''))
Execute(The opa fmt callback should include custom options):
let g:ale_opa_fmt_options = "--list"
AssertEqual
\ {
\ 'command': ale#Escape('xxxinvalid')
\ . ' fmt'
\ . ' ' . g:ale_opa_fmt_options
\ },
\ ale#fixers#opafmt#Fix(bufnr(''))

View File

@ -0,0 +1,16 @@
" Based upon :help ale-development
Before:
call ale#assert#SetUpLinterTest('rego', 'opacheck')
After:
call ale#assert#TearDownLinterTest()
Execute(The default command should be correct):
AssertLinter 'opa',
\ ale#Escape('opa') . ' check %s --format json '
Execute(The default command should be overriden):
let b:ale_rego_opacheck_executable = '/bin/other/opa'
AssertLinter '/bin/other/opa',
\ ale#Escape('/bin/other/opa') . ' check %s --format json '