Allow hadolint linter to run via docker image (#720)

* Add documentation for hadolint (doc/ale-hadolint.txt)

* Allow `hadolint` linter to run via docker image

These changes enable the `hadolint` linter to run via the author's
docker image, if present.   Three modes are supported:

 * never use docker;
 * always use docker; and
 * use docker as a failback.
This commit is contained in:
Chris Weyl 2017-07-03 09:37:32 -05:00 committed by w0rp
parent 51f256e897
commit 5a3cfbbdf5
3 changed files with 148 additions and 2 deletions

View File

@ -1,5 +1,9 @@
" Author: hauleth - https://github.com/hauleth " Author: hauleth - https://github.com/hauleth
" always, yes, never
call ale#Set('dockerfile_hadolint_use_docker', 'never')
call ale#Set('dockerfile_hadolint_docker_image', 'lukasmartinelli/hadolint')
function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort
" Matches patterns line the following: " Matches patterns line the following:
" "
@ -29,9 +33,45 @@ function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort
return l:output return l:output
endfunction endfunction
" This is a little different than the typical 'executable' callback. We want
" to afford the user the chance to say always use docker, never use docker,
" and use docker if the hadolint executable is not present on the system.
"
" In the case of neither docker nor hadolint executables being present, it
" really doesn't matter which we return -- either will have the effect of
" 'nope, can't use this linter!'.
function! ale_linters#dockerfile#hadolint#GetExecutable(buffer) abort
let l:use_docker = ale#Var(a:buffer, 'dockerfile_hadolint_use_docker')
" check for mandatory directives
if l:use_docker ==# 'never'
return 'hadolint'
elseif l:use_docker ==# 'always'
return 'docker'
endif
" if we reach here, we want to use 'hadolint' if present...
if executable('hadolint')
return 'hadolint'
endif
"... and 'docker' as a fallback.
return 'docker'
endfunction
function! ale_linters#dockerfile#hadolint#GetCommand(buffer) abort
let l:command = ale_linters#dockerfile#hadolint#GetExecutable(a:buffer)
if l:command ==# 'docker'
return 'docker run --rm -i ' . ale#Var(a:buffer, 'dockerfile_hadolint_docker_image')
endif
return 'hadolint -'
endfunction
call ale#linter#Define('dockerfile', { call ale#linter#Define('dockerfile', {
\ 'name': 'hadolint', \ 'name': 'hadolint',
\ 'executable': 'hadolint', \ 'executable_callback': 'ale_linters#dockerfile#hadolint#GetExecutable',
\ 'command': 'hadolint -', \ 'command_callback': 'ale_linters#dockerfile#hadolint#GetCommand',
\ 'callback': 'ale_linters#dockerfile#hadolint#Handle', \ 'callback': 'ale_linters#dockerfile#hadolint#Handle',
\}) \})

37
doc/ale-dockerfile.txt Normal file
View File

@ -0,0 +1,37 @@
===============================================================================
ALE Dockerfile Integration *ale-dockerfile-options*
-------------------------------------------------------------------------------
hadolint *ale-dockerfile-hadolint*
hadolint can be found at: https://github.com/lukasmartinelli/hadolint
g:ale_dockerfile_hadolint_use_docker *g:ale_dockerfile_hadolint_use_docker*
*b:ale_dockerfile_hadolint_use_docker*
Type: |String|
Default: `'never'`
This variable controls if docker and the hadolint image are used to run this
linter: if 'never', docker will never be used; 'always' means docker will
always be used; 'yes' and docker will be used if the hadolint executable
cannot be found.
For now, the default is 'never'. This may change as ale's support for using
docker to lint evolves.
g:ale_dockerfile_hadolint_image *g:ale_dockerfile_hadolint_image*
*b:ale_dockerfile_hadolint_image*
Type: |String|
Default: `'lukasmartinelli/hadolint'`
This variable controls the docker image used to run hadolint. The default
is hadolint's author's build, and can be found at:
https://hub.docker.com/r/lukasmartinelli/hadolint/
-------------------------------------------------------------------------------
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@ -0,0 +1,69 @@
" NOTE: We use the 'b:' forms below to ensure that we're properly using
" ale#Var()
Given dockerfile:
#
Before:
Save g:ale_dockerfile_hadolint_use_docker
Save g:ale_dockerfile_hadolint_docker_image
silent! unlet g:ale_dockerfile_hadolint_use_docker
silent! unlet g:ale_dockerfile_hadolint_docker_image
" enable loading inside test container
silent! cd /testplugin
source ale_linters/dockerfile/hadolint.vim
After:
Restore
silent! unlet b:ale_dockerfile_hadolint_use_docker
silent! unlet b:ale_dockerfile_hadolint_docker_image
Execute(linter honors ..._use_docker correctly):
" default: never
AssertEqual
\ 'hadolint',
\ ale_linters#dockerfile#hadolint#GetExecutable(bufnr(''))
" explicit never
let b:ale_dockerfile_hadolint_use_docker = 'never'
AssertEqual
\ 'hadolint',
\ ale_linters#dockerfile#hadolint#GetExecutable(bufnr(''))
let b:ale_dockerfile_hadolint_use_docker = 'always'
AssertEqual
\ 'docker',
\ ale_linters#dockerfile#hadolint#GetExecutable(bufnr(''))
" hadolint if present, otherwise docker
let command = 'docker'
if executable('hadolint')
let command = 'hadolint'
endif
let b:ale_dockerfile_hadolint_use_docker = 'yes'
AssertEqual
\ command,
\ ale_linters#dockerfile#hadolint#GetExecutable(bufnr(''))
Execute(command is correct when using docker):
let b:ale_dockerfile_hadolint_use_docker = 'always'
AssertEqual
\ "docker run --rm -i lukasmartinelli/hadolint",
\ ale_linters#dockerfile#hadolint#GetCommand(bufnr(''))
Execute(command is correct when not docker):
let b:ale_dockerfile_hadolint_use_docker = 'never'
AssertEqual
\ "hadolint -",
\ ale_linters#dockerfile#hadolint#GetCommand(bufnr(''))
" fin...