Add rpm spec file linter (rpmlint) (#486)
* Initial attempt at an rpmlint linter. * Add some basic documentation. * Play with indentation in the test file. * Another attempt to fix the rpmlint test. * Hopefully this does it.
This commit is contained in:
parent
d8dcc56af5
commit
4eeb4783d3
@ -95,6 +95,7 @@ name. That seems to be the fairest way to arrange this table.
|
||||
| Puppet | [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) |
|
||||
| Python | [flake8](http://flake8.pycqa.org/en/latest/), [mypy](http://mypy-lang.org/), [pylint](https://www.pylint.org/) |
|
||||
| reStructuredText | [proselint](http://proselint.com/)|
|
||||
| RPM spec | [rpmlint](https://github.com/rpm-software-management/rpmlint) |
|
||||
| Ruby | [rubocop](https://github.com/bbatsov/rubocop), [ruby](https://www.ruby-lang.org) |
|
||||
| Rust | [rustc](https://www.rust-lang.org/), cargo (see `:help ale-integration-rust` for configuration instructions) |
|
||||
| SASS | [sass-lint](https://www.npmjs.com/package/sass-lint), [stylelint](https://github.com/stylelint/stylelint) |
|
||||
|
85
ale_linters/spec/rpmlint.vim
Normal file
85
ale_linters/spec/rpmlint.vim
Normal file
@ -0,0 +1,85 @@
|
||||
" Author: Jason Tibbitts <tibbs@math.uh.edu>
|
||||
" Description: Adds support for checking RPM spec files with rpmlint
|
||||
|
||||
" rpmlint will produce varions types of output:
|
||||
"
|
||||
" Lines like the following are output when the file is simply not able to be
|
||||
" parsed by rpmspec -P:
|
||||
" apcupsd.spec: E: specfile-error warning: bogus date in %changelog: Mon Oct 1 2005 - Foo
|
||||
" apcupsd.spec: E: specfile-error error: %changelog not in descending chronological order
|
||||
" They do not contain a line number, and there's not a whole lot that can be
|
||||
" done to locate them besides grep for them. rpmlint is just passing the
|
||||
" output from rpm along with the filename, an error indicator, and an error
|
||||
" type.
|
||||
"
|
||||
" Lines like the following:
|
||||
" cyrus-imapd.spec:23: W: macro-in-comment %version
|
||||
" cyrus-imapd.spec:18: E: hardcoded-library-path in %_prefix/lib/%name
|
||||
" indicate warnings and errors, respectively. No column numbers are provided
|
||||
"
|
||||
" Lines like:
|
||||
" apcupsd.spec: I: checking
|
||||
" apcupsd.spec: I: checking-url https://downloads.sourceforge.net/apcupsd/apcupsd-3.14.14.tar.gz (timeout 10 seconds)
|
||||
" are merely informational and are only output when -v is passed. But they
|
||||
" may be useful in a log to know why things are taking so long.
|
||||
"
|
||||
" And this is always output at the end and should just be ignored:
|
||||
" 0 packages and 1 specfiles checked; 4 errors, 0 warnings.
|
||||
|
||||
let g:ale_spec_rpmlint_executable =
|
||||
\ get(g:, 'ale_spec_rpmlint_executable', 'rpmlint')
|
||||
|
||||
let g:ale_spec_rpmlint_options =
|
||||
\ get(g:, 'ale_spec_rpmlint_options', '')
|
||||
|
||||
function! ale_linters#spec#rpmlint#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'spec_rpmlint_executable')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#spec#rpmlint#GetCommand(buffer) abort
|
||||
return ale_linters#spec#rpmlint#GetExecutable(a:buffer)
|
||||
\ . ' ' . ale#Var(a:buffer, 'spec_rpmlint_options')
|
||||
\ . ' -o "NetworkEnabled False"'
|
||||
\ . ' -v'
|
||||
\ . ' %t'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#spec#rpmlint#Handle(buffer, lines) abort
|
||||
" let l:pat_inform = '^.\+: I: \(.+\)'
|
||||
let l:pat_errwarn = '^.\+:\(\d\+\): \([EW]\): \(.\+\)'
|
||||
let l:pat_baderr = '^.\+: E: \(.\+\)'
|
||||
let l:output = []
|
||||
|
||||
for l:line in a:lines
|
||||
let l:match_errwarn = matchlist(l:line, l:pat_errwarn)
|
||||
let l:match_baderr = matchlist(l:line, l:pat_baderr)
|
||||
|
||||
if len(l:match_errwarn) > 0
|
||||
let l:text = l:match_errwarn[3]
|
||||
let l:type = l:match_errwarn[2]
|
||||
let l:lnum = l:match_errwarn[1] + 0
|
||||
elseif len(l:match_baderr) > 0
|
||||
let l:text = l:match_baderr[1]
|
||||
let l:type = 'E'
|
||||
let l:lnum = 1
|
||||
else
|
||||
continue
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'bufnr': a:buffer,
|
||||
\ 'lnum': l:lnum,
|
||||
\ 'text': l:text,
|
||||
\ 'type': l:type,
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('spec', {
|
||||
\ 'name': 'rpmlint',
|
||||
\ 'executable_callback': 'ale_linters#spec#rpmlint#GetExecutable',
|
||||
\ 'command_callback': 'ale_linters#spec#rpmlint#GetCommand',
|
||||
\ 'callback': 'ale_linters#spec#rpmlint#Handle',
|
||||
\})
|
28
doc/ale-spec.txt
Normal file
28
doc/ale-spec.txt
Normal file
@ -0,0 +1,28 @@
|
||||
===============================================================================
|
||||
ALE RPM Spec Integration *ale-spec-options*
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
rpmlint *ale-spec-rpmlint*
|
||||
|
||||
g:ale_spec_rpmlint_executable *g:ale_spec_rpmlint_executable*
|
||||
|
||||
Type: |String|
|
||||
Default: `'rpmlint'`
|
||||
|
||||
This variable sets executable used for rpmlint.
|
||||
|
||||
|
||||
g:ale_spec_rpmlint_options *g:ale_spec_rpmlint_options*
|
||||
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
Set this to pass extra arguments to rpmlint.
|
||||
|
||||
For example, to instruct rpmlint to use a specific configuration file:
|
||||
|
||||
let g:ale_spec_rpmlint_options = '-f custom.cf'
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
@ -71,6 +71,8 @@ CONTENTS *ale-contents*
|
||||
sh....................................|ale-sh-options|
|
||||
shell...............................|ale-sh-shell|
|
||||
shellcheck..........................|ale-sh-shellcheck|
|
||||
spec..................................|ale-spec-options|
|
||||
rpmlint.............................|ale-spec-rpmlint|
|
||||
tex...................................|ale-tex-options|
|
||||
chktex..............................|ale-tex-chktex|
|
||||
lacheck.............................|ale-tex-lacheck|
|
||||
@ -151,6 +153,7 @@ The following languages and tools are supported.
|
||||
* Puppet: 'puppet', 'puppet-lint'
|
||||
* Python: 'flake8', 'mypy', 'pylint'
|
||||
* reStructuredText: 'proselint'
|
||||
* RPM spec: 'spec'
|
||||
* Rust: 'rustc' (see |ale-integration-rust|)
|
||||
* Ruby: 'rubocop'
|
||||
* SASS: 'sasslint', 'stylelint'
|
||||
|
29
test/handler/test_rpmlint_handler.vader
Normal file
29
test/handler/test_rpmlint_handler.vader
Normal file
@ -0,0 +1,29 @@
|
||||
Execute(The rpmlint handler should parse error messages correctly):
|
||||
runtime ale_linters/spec/rpmlint.vim
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'bufnr': 42,
|
||||
\ 'lnum': 23,
|
||||
\ 'text': 'macro-in-comment %version',
|
||||
\ 'type': 'W',
|
||||
\ },
|
||||
\ {
|
||||
\ 'bufnr': 42,
|
||||
\ 'lnum': 17,
|
||||
\ 'text': 'hardcoded-library-path in %_prefix/lib/%name',
|
||||
\ 'type': 'E',
|
||||
\ },
|
||||
\ {
|
||||
\ 'bufnr': 42,
|
||||
\ 'lnum': 1,
|
||||
\ 'text': 'specfile-error warning: bogus date in %changelog: Mon Oct 1 2005 - Foo',
|
||||
\ 'type': 'E',
|
||||
\ },
|
||||
\ ],
|
||||
\ ale_linters#spec#rpmlint#Handle(42, [
|
||||
\ 'cyrus-imapd.spec:23: W: macro-in-comment %version',
|
||||
\ 'cyrus-imapd.spec:17: E: hardcoded-library-path in %_prefix/lib/%name',
|
||||
\ 'apcupsd.spec: E: specfile-error warning: bogus date in %changelog: Mon Oct 1 2005 - Foo',
|
||||
\ ])
|
Loading…
Reference in New Issue
Block a user